SQL2 Functions and Operators
Introduction
The SQL2 API supports a broad array of functions and operators for use within an SQL query. This page outlines the currently implemented functions and operators, and highlights any differences in behavior or functionality between versions 1 and 2 of the SQL implementation, as well as between SQL2 and PostgreSQL.
Warning
Only the Functions and Operators listed below are currently supported by SQL2.
Info
Functions used in SQL queries are case-insensitive. If for example you are taking a max
on a table column, one can use max
, MAX
, or even mAx
.
Datatypes
This section regularly mentions the datatypes that can be used as inputs to functions and the datatypes that those functions can return. The table below maps PostgreSQL datatypes to kdb+ datatypes:
PostgreSQL Datatype | kdb+ Datatype |
---|---|
bigint | long |
int | int |
smallint | short |
tinyint | byte |
bit | boolean |
decimal | real/float |
numeric | real/float |
datetime | timestamp |
smalldatetime | datetime |
date | date |
varchar | string |
text | string |
nchar | string |
nvarchar | string |
ntext | string |
The following shorthand notations are often used to refer to multiple types:
PostgreSQL Shorthand Notation | kdb+ Datatype |
---|---|
numeric_type |
long, int, short, byte, boolean, real, date, timestamp, datetime |
positive_numeric |
A numeric_type with value greater than 0 |
temporal_type |
timestamp, datetime, date |
any_type |
all types |
For more information on kdb+ datatypes, visit the kdb+ datatypes documentation.
Note
In kdb+, timestamp
, datetime
and date
are treated as a numeric types and as such can be used in arithmetic functions, etc. This is a notable difference from PostgreSQL which does not support this.
Warning
PostgreSQL types such as binary
, varbinary
, and image
are not currently supported.
Aggregations
The following functions are commonly used with GROUP BY
to aggregate a series of values into a single atomic value.
Function | Input -> Output Type | Description | Example Query |
---|---|---|---|
sum | sum(numeric_type) -> numeric_type | Computes the sum of numeric values. | sum(array[10, 20]) -> 30 |
avg | avg(numeric_type) -> float | Computes the average of numeric values. | avg(array[10, 20]) -> 15 |
count | count(any_type) -> long | Returns the count of elements passed to it. | count(array[10, 20]) -> 2 |
first | first(any_type) -> any_type | Returns the first element of a list. | first(array[10, 20]) -> 10 |
last | last(any_type) -> any_type | Returns the last element of the list. | last(array[10, 20]) -> 20 |
min | min(numeric_type)-> numeric_type min(temporal_type)-> temporal_type |
Returns the lowest value from a list. | min(array[10, 5, 25, 20]) -> 5 |
max | max(numeric_type)-> numeric_type max(temporal_type)-> temporal_type |
Returns the largest value from a list. | max(array[10, 5, 25, 20]) -> 25 |
prod | prod(numeric_type) -> numeric_type | Multiplies all the elements of a list together. | prod(array[10, 5, 25, 20]) -> 250000 |
var | var(numeric_type) -> float | Calculates the statistical variance of a list of values. | var(array[10, 20, 30]) -> 66.66667 |
dev | dev(numeric_type) -> float | Calculates the standard deviation of a list of values. | dev(array[10, 20, 30]) -> 8.164966 |
stddev | stddev(numeric_type) -> float | Calculates the sample deviation of a list of values. | stddev(array[10, 20, 30]) -> 10 |
svar | svar(numeric_type) -> float | Calculates the sample variance of a list of values. | svar(array[10, 20, 30]) -> 100 |
wsum | wsum(numeric_type, numeric_type) -> float | Calculates the weighted sum of a list of values. | wsum(array[1, 2, 3], array[10, 20, 30]) -> 140 |
wavg | wavg(numeric_type, numeric_type) -> float | Computes the weighted average. | wavg(array[1, 2, 3], array[10, 20, 30]) -> 23.333333 |
Differences from PostgreSQL
-
The current implementation does not support using
min
(ormax
) on symbols and strings to find the first (or last) element of the list in lexicographical order. -
The aggregation
prod()
behaves the same way as the q implementation ofprd()
.
Mathematical Functions
The SQL2 API provides a variety of mathematical operators and functions. These are described in the following table:
Function | Input -> Output Type | Description | Example Query |
---|---|---|---|
abs | abs(numeric_type) -> numeric_type | Returns the absolute value of a number. | abs(-25) -> 25 |
ceil | ceil(numeric_type) -> long | Rounds a number up to nearest long. | ceil(12.5) -> 13 |
ceiling | ceiling(numeric_type) -> long | Rounds a number up to nearest long. | ceiling(12.5) -> 13 |
floor | floor(numeric_type) -> long | Rounds a number down to nearest long. | floor(12.5) -> 12 |
round | round(numeric_type, long) -> float | Rounds a number to as many decimal places as second argument. | round(10.325, 2) -> 10.33 |
width_bucket[2] | width_bucket(numeric_type, numeric_type[]) -> long width_bucket(temporal_type, temporal_type[]) -> long |
Returns the bucket number to which the first value belongs in based on the array list of values in the second argument. | width_bucket(35, array[0, 25, 50, 75, 100]) -> 2 |
width_bucket[4] | width_bucket(numeric_type, numeric_type, numeric_type, numeric_type) -> numeric_type width_bucket(temporal_type, temporal_type, temporal_type, temporal_type) -> temporal_type |
Converts a numerical or temporal value into a number representing which bucket it would be assigned to. First argument defines the expression to bucket, second and third arguments set the min and max values, and the last argument sets the number of buckets. | width_bucket(35, 0, 100, 4) -> 2 |
neg | neg(numeric_type) -> numeric_type | Returns the negative value of a number. | neg(-10) -> 10 |
degrees | degrees(numeric_type) -> numeric_type | Converts a value in degrees to radians. | degrees(3.141593) -> 180. |
radians | radians(numeric_type) -> numeric_type | Converts a value in radians to degrees. | radians(180) -> 3.141593. |
factorial | factorial(positive_numeric) -> positive_numeric | Applies the factorial function n! . Must be a positive number. |
factorial(4) -> 24 |
div | div(numeric_type, numeric_type) -> long | Returns the long remainder of a number divided by another number. |
div(10, 3) -> 3 |
log | log(numeric_type) -> float | Performs a logarithm with base 10. | log(10) -> 1 |
log10 | log10(numeric_type) -> float | Performs a logarithm with base 10. | log10(100) -> 2 |
ln | log(numeric_type) -> float | Performs a logarithm with base 'e'. | ln(2.718) -> 0.99989... |
exp | exp(numeric_type) -> float | Performs an exponent with number 'e'. | exp(1) -> 2.71828... |
gcd | gcd(long, long)-> long | Calculates the greatest common divisor between two numbers, or two lists of numbers. | gcd(10, 20) -> 10 |
lcm | lcm(long, long) -> long | Calculates the least common multiple between two numbers, or two lists of numbers. | lcm(75, 50) -> 150 |
pi | pi() -> float | Returns the value of pi , e.g 3.14159.. |
pi() -> 3.14159... |
power | power(numeric_type, numeric_type) -> float | Computes the first argument to the power of the second argument. | power(10, 2) -> 100 |
trunc[1] | trunc(numeric_type) -> long | Returns the integer part of a number. | trunc(10.25368) -> 10 |
trunc[2] | trunc(numeric_type, long) -> numeric_type | Returns the first argument to as many decimal points as the second argument. | trunc(10.25368, 2) -> 10.25 |
sqrt | sqrt(numeric_type) -> float | Returns the square root of a numeric type. | sqrt(25) -> 5 |
cbrt | cbrt(numeric_type) -> float | Returns the cubed root of a numeric type. | cbrt(125) -> 5 |
Differences from PostgreSQL
- The
trunc[2]
andround
functions may return an incorrect number of decimal places depending on the\P
setting of the kdb console receiving the data. For example, in test done on kdb+ with a\P
of 17, the following callround(10.2536851231561315315, 13)
returned a value of10.253685123156099
instead of10.2536851231561
. This is an artifact of the way kdb+ handles floats and display precision. Read more here
Mathematical Operators
The following operators are used in expressing arithmetical expressions or to do bitwise operations.
Function | Input -> Output Type | Description | Example Query |
---|---|---|---|
+ | numeric_type + numeric_type -> numeric_type | Performs addition on the two arguments. | 10 + 5 -> 15 |
- | numeric_type - numeric_type -> numeric_type | Performs subtraction on the two arguments. | 10 - 5 -> 5 |
* | numeric_type * numeric_type -> numeric_type | Performs multiplication on the two arguments. | 10 * 5 -> 50 |
/ | numeric_type / numeric_type -> numeric_type | Performs division on the two arguments. | 10 / 5 -> 2 |
@ | @ numeric_type -> numeric_type | Returns the absolute value of a number. Operator form of abs . |
@ -25 -> 25 |
% | numeric_type % numeric_type -> numeric_type | Performs a modulo operation of first argument modulo second argument. | 9 % 5 -> 4 |
^ | numeric_type ^ numeric_type -> numeric_type | Performs an exponent operation of first argument to the power of the second argument. | 2 ^ 3 -> 8 |
\|/ |
\|/ numeric_type -> float |
Takes the square root of a number. | \|/ 25 -> 5 |
\|\|/ |
\|\|/ numeric_type -> float |
Takes the cubed root of a number. | \|\|/ 125 -> 5 |
& | numeric_type & numeric_type -> numeric_type | Does a bitwise AND of the two arguments. | 42 & 35 -> 34 |
\| |
numeric_type \| numeric_type -> numeric_type |
Does a bitwise OR of the two arguments. | 42 \| 35 -> 43 |
~ | ~ numeric_type -> numeric_type | Does a bitwise NOT. | ~ 42 -> -43 |
# | # numeric_type -> numeric_type | Does a bitwise XOR. | 42 # 35 -> 9 |
<< | numeric_type << numeric_type -> numeric_type | Performs a bitwise left shift. | 35 << 2 -> 140 |
>> | numeric_type >> numeric_type -> numeric_type | Performs a bitwise right shift. | 35 >> 2 -> 8 |
Logical Operators
Named functions to specifically perform logical operations after the WHERE
clause of a query are listed below:
Function | Input Type | Description | Example Query |
---|---|---|---|
AND | any_type condition AND any_type condition | Data set returned from the query must comply with all conditions applied in the WHERE clause. | SELECT * FROM table WHERE condition1 AND condition2 ... AND condition_n |
OR | any_type condition OR any_type condition | Data set returned from query must comply with at least one of the conditions applied in the WHERE clause. | SELECT * FROM table WHERE condition1 OR condition2 ... OR condition_n |
NOT | NOT any_type condition | Data set will exclude data that is specified in the NOT condition. | SELECT * FROM table WHERE NOT condition1 |
Comparison Operators and Functions
Function | Input -> Output Type | Description | Example Query |
---|---|---|---|
= | any_type = any_type -> boolean | Equality operator. Checks whether arguments are equal to each other. | 10 = 11 -> false |
!= | any_type != any_type -> boolean | Non-equality operator. Checks whether arguments are not equal to each other. | 10 != 11 -> true |
> | any_type > any_type -> boolean | Greater than operator. Checks whether left argument is larger than right argument. | 10 > 11 -> false |
< | any_type < any_type -> boolean | Less than operator. Checks whether left argument is smaller than right argument. | 10 < 11 -> true |
>= | any_type >= any_type -> boolean | Greater than or equal to operator. Checks whether the left argument is larger than or equal to right argument. | 10 >= 11 -> false |
<= | any_type <= any_type -> boolean | Less than or equal to operator. Checks whether the left argument is smaller than or equal to right argument. | 10 <= 11 -> true |
in | any_type in any_type[] | Returns the values in the left argument are in the list of the right argument. | 'ABC' in ('ABD', 'DEF') -> false 'ABC' in ('ABD', 'DEF', 'ABC') -> true |
!< | any_type !< any_type -> boolean | Returns whether the values in the left argument are not less than the arguments on the right. | 100.0 !< 120 -> false |
!> | numeric_type !> numeric_type | Returns whether the values in the left argument are not greater than the arguments on the right. | 100.0 !> 120 -> true |
between | any_type BETWEEN any_type AND any_type | Returns if the left argument is between the two right arguments. | 'c' between 'a' AND 'd' -> true 10 between 5 9 -> false |
like | string_type like 'SEARCH_STRING' | The kdb+ string or symbol text matching operator. Does not support full set of regex. See here. | select avg(price) from trade where sym like 'MS*' select avg(price) from trade where sym like '*LE' select avg(price) from trade where sym like '*L*' |
Differences from SQL
- Unlike SQL, the
like
operator in SQL2 does not support the full PostgreSQL regex. Instead, it behaves like the kdb+ functionlike
. For more information, see kdb+ like function. - The
sqrt
andcbrt
functions currently do not support negative numbers.
Differences from PostgreSQL
- The
like
operator in SQL2 does not support the full PostgreSQL regex. Instead, it behaves like the kdb+ functionlike
. For more information, see kdb+ like function. - The
=
operator in SQL2 cannot be used on string types, unlike in PostgreSQL. Use thein
operator instead. - The
>
operator does not work on alphabetical lists.
Miscellaneous Functions
Function | Input -> Output Type | Description | Example Query |
---|---|---|---|
cast |
cast(any_type as kdb+ Datatype) -> boolean |
Casts a value from one type to another type. | cast(10.5 as bigint) -> 11 cast('2024-01-01 11:00:00' as date) -> '2024-01-01' |
lower |
lower(string_type) -> string_type |
Converts all characters in a string or symbol to be lower case. | lower('ABC') -> 'abc' |
upper |
upper(string_type) -> string_type |
Converts all characters in a string or symbol to be upper case. | upper('abc') -> 'ABC' |
date_trunc |
date_trunc(string, temporal_type) -> datetime |
Truncates temporal type to given precision. | date_trunc('hour', '2020-10-17 01:01:01') -> 2020-10-17 01:00:00 |
date_part |
date_part(string, temporal_type) -> numeric |
Retrieves subfields from a temporal. | date_part('hour', '2020-10-17 21:01:01') -> 21 |
extract |
extract(subfield from temporal_type) -> numeric |
Retrieves subfields from a temporal. | extract(hour from '2020-10-17 21:01:01') -> 21 |
random |
random() -> numeric |
Returns a random value in the range 0.0 <= x < 1.0. | random() -> 0.23195317712191965 |
sedseed |
sedseed(float_type) |
Sets the seed for subsequent random() calls; argument must be between -1.0 and 1.0, inclusive. | sedseed(0.5) |
Differences from PostgreSQL
- Casting to
binary
,varbinary
, andimage
are not currently supported. - Calling
date_trunc("millennium", time)
on dates prior to 2000.01.01 will result in negative infinity-0W
, as kdb+ cannot create a timestamp with year 1001.01.01.