Operators
Comparison
Two values can be compared using standard SQL comparison operators:
=,==(equals)>(greater than)<(less than)>=(greater than or equal to)<=(less than or equal to)<>,!=(not equal to)
SELECT * FROM products WHERE NOT name = 'Coffee';
SELECT * FROM products WHERE name = 'Coffee' AND name <> 'Kaapi';
SELECT * FROM products WHERE name > 'Cake' AND price >= 5.00;
BETWEEN
BETWEEN returns TRUE when a value is greater-than-or-equal-to the first limit
and less-than-or-equal-to the second.
It has the form BETWEEN x AND y.
It can be negated with the form NOT BETWEEN x AND y.
SELECT * FROM products WHERE price BETWEEN 2.00 AND 4.00;
SELECT * FROM products WHERE price NOT BETWEEN 2.00 AND 4.00;
NOTE: BETWEEN can also be used with System Time.
Boolean Operators
WHERE and HAVING clauses can be modified and combined with standard SQL boolean operators.
IS, IS NOT
IS and IS NOT behave like = (==) and <> (!=), respectively.
They are usually used to augment equality checks to test for NULL,
which is the third boolean value, representing "unknown".
The literal UNKNOWN is permitted in IS / IS NOT expressions in place of NULL.
- When both sides of
ISevaluate toNULLit returnsTRUE. - When only one side of
IS NOTevaluates toNULLit returnsTRUE, - When only one side of
ISevaluates toNUllit returnsFALSE. - When both sides of
IS NOTevaluates toNULLit returnsFALSE.
SELECT * FROM products WHERE product_no IS NULL;
SELECT * FROM products WHERE product_no IS UNKNOWN;
SELECT * FROM products WHERE product_no IS NOT NULL;
SELECT * FROM products WHERE product_no IS 386;
SELECT * FROM products WHERE product_no IS NOT 444;
NOTE: A WHERE clause of the form <column> IS NULL will not return
rows for which <column> does not exist, as positive equality is only
tested against extant columns.
For example, the query SELECT * FROM products WHERE name IS NULL; will
not return rows for which the column name does not exist.
However, SELECT * FROM products WHERE name IS NOT NULL; will not return
either rows where the name column has a value of NULL or the name
column is missing.
Thus, IS and IS NOT are not symmetrical for jagged data.
IS [NOT] DISTINCT FROM
IS DISTINCT FROM is a synonym for IS NOT.
IS NOT DISTINCT FROM is a synonym for IS.
NOTE: The IS [NOT] DISTINCT FROM form is provided for SQL specification
compatibility and is not recommended, as it tends to be verbose and confusing.
NOT, AND, OR
NOT can be prefixed to any clause to negate it:
SELECT * FROM products WHERE NOT (name = 'Coffee');
AND returns true if two clauses both return true:
SELECT * FROM products WHERE name = 'Coffee' AND price > 2.99;
OR returns true if either of two clauses return true:
SELECT * FROM products WHERE name = 'Coffee' OR name = 'Kaapi';
Math
Standard SQL mathemetical operators are available to any two numeric values:
+(addition)-(subtraction)*(multiplication)/(division)%(modulo; integer remainder of division)<<(left bit shift)>>(right bit shift)+NUMBER(unary plus)-NUMBER(unary minus)
SELECT 1 + 3.555;
SELECT 1 - 3.555;
SELECT 2 * 3.555;
SELECT 2 / 3.555;
SELECT 2 % 3.555;
SELECT 62 << 2;
SELECT 62 >> 2;
SELECT +128.5;
SELECT -128.5;
NOTE: Mathematical functions are documented under Functions.
Bitwise Operators
Standard SQL bitwise manipulation operators are available to any two values.
&(bitwise and)|(bitwise or)
The bitwise not operator is also available to a single value:
~(bitwise not)
SELECT 1 & 2;
SELECT 1 | 2;
SELECT ~1;
LIKE
LIKE is the operator equivalent of the LIKE function.
LIKE returns TRUE if a string matches the supplied LIKE pattern, as defined below:
A pattern can be a string literal.
It can also contain underscores (_) and/or percentage symbols (%).
An underscore matches exactly one character.
A percentage symbol matches zero or more characters.
Backslash escapes the following character to make it a literal.
Use ESCAPE to override the default backslash escape character.
SELECT * FROM products WHERE name LIKE 'Tofu';
SELECT * FROM products WHERE name LIKE 'Tof_';
SELECT * FROM products WHERE name LIKE '%of%';
SELECT * FROM products WHERE name LIKE '\%of\%';
SELECT * FROM products WHERE name LIKE 'X%ofX%' ESCAPE 'X';
NOT LIKE is used to invert the results of the match.
SELECT * FROM products WHERE name NOT LIKE '%of%';
NOTE: Endb LIKE is case-sensitive.
REGEXP
REGEXP returns TRUE if a string matches the supplied regular expression.
REGEXP may be prefixed with NOT.
SELECT * FROM products WHERE name REGEXP '.*ee|.*ea';
SELECT * FROM products WHERE name NOT REGEXP '.*[fst]+.*';
GLOB
GLOB returns TRUE if a string matches the supplied UNIX glob.
GLOB may be prefixed with NOT.
SELECT * FROM products WHERE name GLOB '*of*';
SELECT * FROM avatars WHERE filename NOT GLOB '/opt/local/avatars/*/*.png';
NOTE: GLOB is case-sensitive.
It conforms to standard UNIX globs and thus does not support "globstar"
(recursive directory) expansion like **/*.png.
MATCH (Containment)
MATCH returns TRUE if the value on the left contains the value on the right,
at the top level.
Note that a top-level array to the right of the MATCH refers to a set of values
that all need to match, not a literal array.
The following expressions return TRUE:
SELECT 'foo' MATCH 'foo';
SELECT [1, 2, 3] MATCH [3, 1];
SELECT {user: 'foo', age: 42} MATCH {age: 42};
SELECT {a: [1, 2, {c: 3, x: 4}], c: 'b'} MATCH {a: [{x: 4}, 1]};
The following expressions return FALSE:
SELECT [1, 2, [1, 3]] MATCH [1, 3];
SELECT {foo: {bar: 'baz'}} MATCH {bar: 'baz'};
SELECT {a: [1, 2, {c: 3, x: 4}], c: 'b'} MATCH {a: [{x: 4}, 3]};
NOTE: The @> operator is a synonym for MATCH.
It is provided as a convenience for users accustomed to the equivalent
JSON Containment Operator in Postgres.
It also has a symmetric operator, <@, which returns TRUE if the value on the right
contains the value on the left, at the top level.
No symmetric keyword exists for MATCH.
ANY, SOME
SOME is a synonym for ANY.
ANY qualifies a subquery by comparing a single column or literal value with the result of that subquery.
ANY is used in the form <expression> <operator> ANY (<subquery>).
It returns true if the subquery returns a one or more values for which the operator is true.
The operator must return a boolean and the subquery must return a single column.
SELECT 1500 < SOME (SELECT price FROM products);
ALL
ALL qualifies a subquery by comparing a single column or literal value with the result of that subquery.
ALL is used in the form <expression> <operator> ALL (<subquery>).
It returns true only if all values returned by the subquery are true for the operator provided.
The operator must return a boolean and the subquery must return a single column.
SELECT "ok" = ALL (SELECT status_code FROM statuses);
EXISTS
EXISTS returns TRUE if the subquery which follows it returns at least one row.
SELECT name FROM products WHERE EXISTS (SELECT 1 FROM coupons WHERE name = products.name);
IN
The standard SQL IN clause can be used to test lists and subqueries for containment of a value.
SELECT * FROM products WHERE price IN (5.00, 5.99);
SELECT * FROM products WHERE price IN (SELECT price FROM coupons);
NOTE: Use MATCH to test for containment of a value in an array.
NOT IN
The standard SQL NOT IN clause can be used to test lists and subqueries for absence of a value.
SELECT * FROM products WHERE price NOT IN (5.00, 5.99);
SELECT * FROM products WHERE price NOT IN (SELECT price FROM coupons);
NOTE: Use MATCH to test for absence of a value in an array.
|| (Concatenation)
The || operator concatenates two strings or arrays supplied as arguments.
When concatenating to an array element: other elements, arrays, and blobs are accepted as the second argument.
When concatenating to an array: arrays, blobs, and array elements are accepted as the second argument.
Elements other than strings are cast to strings when concatenated with each other.
Multiple operators can be chained together.
SELECT "Hello" || "World";
SELECT [1, 2, 3] || [4, 5, 6];
SELECT 1 || 2;
SELECT "Hello" || ["World"];
SELECT ["Hello"] || "World";
SELECT "Hello" || "World" || "And" || "Friends";
The Concatenation Operator is equivalent to the CONCAT function.
Vector Operators
Indexing
At the moment, Endb performs exact nearest neighbor search, which provides perfect recall. Endb may support approximate vector indexes in the future, which trade accuracy for speed.
<-> (L2 or Euclidean Distance)
The L2 Distance operator (<->) compares two vectors by
Euclidean distance.
It is symmetrical to the L2_DISTANCE function.
SELECT * FROM (VALUES ([0,0,0]), ([1,2,3]), ([1,1,1]), (NULL), ([1,2,4])) AS t(val) WHERE val NOT NULL ORDER BY t.val <-> [3,3,3];
-- [{'val': [1, 2, 3]},
-- {'val': [1, 2, 4]},
-- {'val': [1, 1, 1]},
-- {'val': [0, 0, 0]}]
<=> (Cosine Distance)
The Cosine Distance operator (<=>) compares two vectors by the complement of their
Cosine Similarity.
It is symmetrical to the COSINE_DISTANCE function.
SELECT val FROM (VALUES ([0,0,0]), ([1,2,3]), ([1,1,1]), ([1,2,4])) AS t(val) WHERE t.val <=> [3,3,3] NOT NULL ORDER BY t.val <=> [3,3,3];
-- [{'val': [1, 1, 1]},
-- {'val': [1, 2, 3]},
-- {'val': [1, 2, 4]}]
<#> (Inverse Inner Product)
The Inverse Inner Product operator (<#>) compares two vectors by the inverse
of their Inner Product.
It is the inverse of the INNER_PRODUCT function.
SELECT val FROM (VALUES ([0,0,0]), ([1,2,3]), ([1,1,1]), (NULL), ([1,2,4])) AS t(val) WHERE val IS NOT NULL ORDER BY t.val <#> [3,3,3];
-- [{'val': [1, 2, 4]},
-- {'val': [1, 2, 3]},
-- {'val': [1, 1, 1]},
-- {'val': [0, 0, 0]}]