Documentation Index
Fetch the complete documentation index at: https://docs.ditto.live/llms.txt
Use this file to discover all available pages before exploring further.
Operator Precedence
Understanding operator precedence is crucial for writing correct DQL expressions. Operators with higher precedence are evaluated first. Use parentheses to override the default precedence.| Operator | Precedence | Description |
|---|---|---|
*, /, % | 40 | Multiplication, division, modulo |
+, - (binary) | 30 | Addition, subtraction |
>>, << | 22 | Bit shift operations |
=, <, >, <=, >=, NEG | 20 | Comparison operators |
BETWEEN | 20 | Range comparison |
IN | 20 | Membership test |
LIKE, ILIKE, SIMILAR TO | 19 | Pattern matching |
IS | 17 | Type/null checking |
NOT | 15 | Logical negation |
AND | 10 | Logical AND |
XOR | 7 | Logical exclusive OR |
OR | 5 | Logical OR |
DQL
When in doubt about precedence, use parentheses to make your intentions explicit. This improves code readability and prevents subtle bugs.
Arithmetic Operators
Arithmetic operators are used to perform operations on numeric values.| Operator | Purpose | Example |
|---|---|---|
| - | A unary operator that denotes a negative value | WHERE field_name = -1 |
| +, - | As binary operators, they add or subtract | WHERE field_name + 1 > 2 |
| * | Multiply | WHERE field_name * 2 > 2 |
| / | Divide | WHERE field_name / 2 > 1 |
| % | Modulo | WHERE field_name % 2 > 1 |
| abs(x) | Absolute value | WHERE abs(field_name) = 1 |
| ceil(x) | Next whole number | WHERE ceil(field_name) > 1 |
| floor(x) | Previous whole number | WHERE floor(field_name) > 1 |
String Operators
Performs various operations onstring scalar types:
| Operator | Purpose | Example |
|---|---|---|
| || | String concatenation | WHERE field_name || 'world' = 'hello world' |
| concat(str, …) | String concatenation | WHERE concat(field_name, 'world') = 'hello world' |
| contains(str, substr) | Returns true if substr is contained in str, otherwise returns false | WHERE contains(field_name, 'hello') |
| starts_with(str, substr) | Returns true if str starts with substr, otherwise returns false | WHERE starts_with(field_name, 'hello') |
| ends_with(str, substr) | Returns true if str ends with substr, otherwise returns false | WHERE ends_with(field_name, 'world') |
| byte_length(str) | Returns the length of str in bytes. Strings in Ditto are encoded in UTF-8, so a character can take up to 4 bytes. | WHERE byte_length(field_name) > 4 |
| char_length(str) character_length(str) | Returns the number of characters in str. | WHERE char_length(field_name) > 4 |
| str LIKE ‘substr%‘ | Returns true if specific character string matches the specified pattern. Available in SDK 4.10 onwards. | WHERE field_name LIKE 'hel%' |
| str ILIKE ‘substr%‘ | Returns true if specific character string matches the specified pattern. Case-insensitive variant of LIKE Available in SDK 4.10 onwards. | WHERE field_name ILIKE 'hel%' |
| str SIMILAR TO ‘pattern’ | Like LIKE but in addition to the % and _ wildcards, also supports regular expression operators such as | (alternatives), [chars] (character lists), and \</\> (word boundaries). Available in SDK 4.11 onwards. | WHERE field_name SIMILAR TO '%(red|blue)%' |
| regexp_like(source, pattern[, flags]) | Returns true if source matches the regular expression specified by pattern Available in SDK 4.9 onwards. | WHERE regexp_like(<your-field>, <regex>, 'i') |
| substr(str, start[, len]) | Returns the portion of str starting from the zero-based character index start, optionally limited to len characters | WHERE substr(field_name, 0, 5) = 'hello' |
| pos(str, substr) | Returns the zero-based character index at which substr is first found in str. Returns -1 if not found. Use >= 0 to test if the substring exists anywhere. | WHERE pos(field_name, 'world') >= 0 |
| upper(str) | Returns str converted to uppercase | WHERE upper(field_name) = 'HELLO' |
| lower(str) | Returns str converted to lowercase | WHERE lower(field_name) = 'hello' |
| lpad(str, len[, char]) | Returns str padded on the left to len characters with space or char. Only the first character in char is used | WHERE lpad(field_name, 10, '0') = '0000001234' |
| rpad(str, len[, char]) | Returns str padded on the right to len characters with space or char. Only the first character in char is used | WHERE rpad(field_name, 10, 'x') = '1234xxxxxx' |
| ltrim(str[, char-list]) | Trims whitespace or the char-list from the start of str | WHERE ltrim(field_name, ' ') = 'hello' |
| rtrim(str[, char-list]) | Trims whitespace or the char-list from the end of str | WHERE rtrim(field_name, ' ') = 'hello' |
| trim(str[, char-list]) | Trims whitespace or the char-list from either end of str. Note: To invoke the function directly, quote the name: `trim`(str) | WHERE `trim`(field_name) = 'hello' |
| TRIM([LEADING|TRAILING|BOTH] expr FROM expr) | Alternative syntax for trim functions: TRIM(LEADING ' ' FROM str) = ltrim(str, ' ') | WHERE TRIM(BOTH ' ' FROM field_name) = 'hello' |
| repeat(str, count) | Returns the input str repeated count times | WHERE repeat('x', 5) = 'xxxxx' |
| split(str, delim) | Returns an array of the parts of str delimited by delim. An empty string delim returns each character as its own array element | WHERE array_length(split(field_name, ',')) > 2 |
| joinstr(sep, val[, val…]) | Returns a string of the val arguments separated by sep. Non-string values (except null/missing) are converted to strings. Array elements are joined individually; nested arrays are flattened. null and missing values short-circuit to return null/missing respectively. | SELECT joinstr(', ', tags) FROM cars |
| POSITION(substr IN str) | Alternative syntax for pos(): returns the zero-based index of substr in str. Returns -1 if not found. | WHERE POSITION('world' IN field_name) >= 0 |
Scalar Type Operators
Indicates which scalar type to interact with:| Operator | Purpose | Example |
|---|---|---|
| is_boolean(x) | Boolean type test | WHERE is_boolean(field_name) |
| is_number(x) | Float, Int, or UInt type test | WHERE is_number(field_name) |
| is_string(x) | String type test | WHERE is_string(field_name) |
| type(x) | Returns a string name representing the type. Returns: boolean, string, integer, float, object, array, binary, null, missing. | WHERE type(field_name) = 'string' |
| json_type(x) | Returns the JSON type name of the value. Returns: boolean, string, number, object, array, binary, null. Returns "null" for MISSING values. Available in SDK 4.5 onwards. | WHERE json_type(field_name) = 'number' |
REGISTER | MAP | ATTACHMENT |
|---|---|---|
* null* boolean* number* binary* string* array* object | object | object |
Conversion Operators
Converts between different value types.| Operator | Purpose | Example |
|---|---|---|
| deserialize_json(str) | Returns the JSON string deserialized into an object. Can be used in INSERT, UPDATE, and WHERE clauses. | WHERE deserialize_json('{"field_name": "blue"}') = 'blue' |
| serialize_json(value) | Returns a JSON-encoded string representation of the input value. Available in SDK 5.0 onwards. | SELECT serialize_json({"a":[1,2,3]}) returns "{\"a\":[1,2,3]}" |
| cast(v, type) | Casts from one value type to another if possible. type can be 'string', 'integer', 'float', 'boolean', or 'binary' (prefix abbreviations like 'int' and 'bool' are also accepted). Composite types (objects and arrays) can be cast to 'string' to produce a JSON-encoded representation. Use TYPE(expr) to match another field’s type, e.g. cast(field_a, TYPE(field_b)). Also supports CAST(v AS type) syntax. Returns MISSING if conversion isn’t possible. | SELECT cast(field_name, 'integer') FROM cars |
Array Operators
The following table provides an overview of interactions witharray. Arrays can be either scalar values in a REGISTER or an input via an argument.
| Operator | Purpose | Example |
|---|---|---|
| array_contains(array, value) | Returns true if the array contains the value, otherwise returns false | WHERE array_contains(:your_array, 'blue') |
| array_contains_null(array) | Returns true if the array contains a NULL value, otherwise returns false | WHERE array_contains_null(field_name) |
| array_length(array) | Returns the length of the array. | WHERE array_length(field_name) > 0 |
Date Operators
| Operator | Purpose | Example |
|---|---|---|
| date_cast(string[,format]) | Converts a string representation of a date (in format) to an epoch millisecond (UTC) value. | WHERE date_cast(t.tm,"hh:mm:ss") >= 8*60*60*1000 |
| tz_offset(string[,format]) | Returns the time zone offset (in minutes) from the string representation of a date (in format). | WHERE tz_offset(t.dt) < tz_offset("America/New_York","TZN") |
| clock([format[,tz]]) | Reports the instant of the function’s execution, as an epoch millisecond (UTC) value or as a string in the given format. | SELECT clock() FROM system:dual |
| date_format(date, format[, tz]) | Returns a string representation of date in the given format, optionally adjusting the time zone. | SELECT date_format(ms(t.dt_no_tz,"DD.MM.YYYY hh:mm:ss"), "", "+0530") FROM tSELECT date_format(timestamp_ms,"") AS iso_string FROM t |
| date_add(date, part, count[, format[, tz]]) | Adds the count ‘part[1]’s to the input date, returning a number for numeric date input and a string for string date input, unless format is provided. If tz is provided, the result is converted from the input time zone to the specified time zone. Negative count values subtract from the input date. | SELECT date_add(coll.date, "day", 10) FROM coll |
| date_sub(date, part, count[, format[, tz]]) | Identical to date_add but count functions with the sign inverted: date_add(...,-1) is equivalent to date_sub(...,1). | SELECT date_sub(c.date, "day", 10) FROM c |
| date_diff(date1, date2, part) | Reports the number (integer) of part elements between the two input dates. | WHERE date_diff(c.dt, c.stamp, "year") < 2 |
| date_part(date, part) | Reports the part[2] of the date. | SELECT date_part(c.dt, "day") FROM c |
| date_trunc(date, part) | Truncates the input date to the part[1], zeroing all subsequent fields. Output is numeric for numeric input and string (ISO-8601 format) for string input. | WHERE t.stamp >= date_trunc(clock(), "mon") |
| date_range(start, end, part, count[, format[, tz]]) | Returns an array of dates from start (inclusive) up to but not including end (exclusive) in count part[1] steps (e.g. one date per month), optionally in a specific format and time zone. Available in SDK 4.11 onwards. | SELECT date_range(‘2025-01-01’, ‘2026-01-01’, ‘mon’, 1) FROM system:dual |
[2] All in [1] plus: weekday (ISO-8601 - Monday is 1), monthname (English full month name only) & tz/timezone (string containing ±hh:mm).
Date format specification
Date formats may be specified using SQL-like representative syntax, or usingstrftime/date-like syntax with percent-sign introduced formatting specifiers (a.k.a. “percent-style”).
If passed as an empty string, ISO-8601 format is assumed. e.g. 2026-01-31T22:15:30+02:00
The percent-style formatting is defined by the Rust chrono package:
- Format specifiers
- This format is similar to that used by the Unix/Linux
datecommand. - Note that
%.fand%.3fformats are equivalent as the date functions operate with millisecond precision and%.fessentially picks between%.3f(millisecond),%.6f(microsecond) and%.9f(nanosecond) based on the precision.
| Sequence | Element | Example | Equivalent |
|---|---|---|---|
YYYY | Century & year | 2026 | %Y |
CC | Century | 20 | %C |
YY | Year | 26 | %y |
MM | Month | 01 | %m |
DD | Day | 31 | %d |
hh | Hours[1] | 14 | %H |
mm | Minutes | 30 | %M |
ss | Seconds | 59 | %S |
.s/.sss | Fractions of a second[2] | .010 | %.f/%.3f |
TZD | Time zone displacement | -0500 | %z |
TZN | Time zone name | Europe/London | %Z |
[2] Since date functions do not operate on fractions beyond milliseconds, these formats can be considered aliases and be used interchangeably.
Examples
date_format(timestamp_ms,"")- convert an epoch millisecond value to an ISO-8601 string.date_format(timestamp_ms,"YYYY-MM-DD")- extract just the date portion of an epoch millisecond timestamp value as a string.date_format(timestamp_ms,"%T")- extract just the time portion of an epoch millisecond timestamp value as a string.
Object Operators
The following table provides an overview of interactions withobject. Objects can be either scalar values in a REGISTER, MAP, Attachment, or an input via an argument.
| Operator | Purpose | Example |
|---|---|---|
| object_length(object) | Returns the number of key-value pairs in the top-level of the object | WHERE object_length(field_name) > 0 |
| object_keys(object) | Returns the top-level keys (field names) of a given object as an array. Available in SDK 4.10 onwards. | WHERE array_contains(object_keys(field_name), 'field_i_want') |
| object_values(object) | Returns the top-level values of a given object as an array. Available in SDK 4.10 onwards. | WHERE array_contains(object_values(value_name), 'value_i_want') |
| object_set(object, field, value[, replace-existing]) | Returns an object with the field set to the provided value. If replace-existing is false (default), an error is raised when overwriting an existing field. Pass true to silently replace. Available in SDK 4.11 onwards. | SELECT object_set(field_name, 'new_key', 'value', true) FROM cars |
| object_unset(object, field[, ignore-missing]) | Returns an object with the specified field removed. If ignore-missing is false (default), an error is raised if the field doesn’t exist. Pass true to silently ignore. | SELECT object_unset(field_name, 'old_key', true) FROM cars |
| object_concat(object1, object2[, …]) | Returns an object that merges the input objects’ top-level fields, with the last specified winning conflicts. | SELECT object_concat(field1, field2) FROM cars |
| object_rename(object, old, new) | Returns an object with the field old renamed to new. Raises an error if old doesn’t exist. If new already exists, it is silently overwritten. | SELECT object_rename(field_name, 'old_key', 'new_key') FROM cars |
| object_content(object[, config…]) | Returns the object content based on configuration options. See detailed description below. Available in SDK 4.11 onwards. | SELECT object_content(field_name, 'keys', 'nested') FROM cars |
| object_size(object) | Returns the approximate size of object. This is just a rough guide for comparing against other object_size results | WHERE object_size(field_name) > 1000 |
object_content() Configuration
Theobject_content() function accepts configuration options to control output format:
Configuration can be an object with optional fields:
output:'fields'(default),'keys', or'values'nested:'no'(default),'yes', or'only'subscripts:false(default) ortrue
'fields','keys','values''nested','nested-only''subscripts'
fields: An array of objects each containing a single field & value pairkeys: An array of string keys (same asobject_keys())values: An array of values (same asobject_values())
no/ not specified: Don’t recursively process fieldsnested/yes: Report the parent field then recursively process its contentsnested-only/only: Don’t report the parent field unless recursive processing yields no results
true: Individual elements are reportedfalse(default): Only unique elements are reported with a subscript of*
subscripts is a boolean value in the config object. The string shortcut 'subscripts' sets it to true.
Duration Operators
Duration operators work with duration strings and convert between different time units.Available in SDK 4.12 onwards.
| Operator | Purpose | Example |
|---|---|---|
| duration_cast(str[, unit-str]) | Returns the integer number of unit-str units (or milliseconds if not specified) represented by the input duration string. Units: “seconds”, “milliseconds”, “ms”, “microseconds”, “us”, “μs”, “nanoseconds”, “ns” | WHERE duration_cast('1h23m54.07s', 'seconds') = 5034 |
| duration_format(value[, unit-str]) | Returns a string with the input value in unit-str units (or milliseconds if not specified) as a duration. The smallest unit reported is seconds with fractional seconds | WHERE duration_format(90000, 'ms') = '1m30s' |
Collection Operators
The following table provides the collection operators for comparing if a given value is equal to any of the values in a list:| Operator | Purpose | Example |
|---|---|---|
| IN (x, y, …) | Membership test | WHERE department IN ('HR', 'Sales') |
| NOT IN (x, y, …) | Non-membership test | WHERE department NOT IN ('HR', 'Sales') |
Array and Object Literals
Since version 4.8 of the Ditto SDK, Array and object literals are supported and can be used inline.SQL
SQL
Array and Object Transformation Expressions
ARRAY and OBJECT transformation expressions are available in SDK v5+.ARRAY Transformation
TheARRAY transformation expression creates a new array by evaluating an expression for each element in a source array or object.
Syntax:
DQL
value_expr- Expression evaluated for each element (result added to output array unlessMISSING)name_var- Optional identifier holding the array index (for arrays) or field name (for objects)value_var- Identifier holding the element valuesource- Expression evaluating to anARRAYorOBJECT- Returns
MISSINGif source isMISSING - Returns
NULLif source is any other non-array/object type
- Returns
condition- Optional filter; element included only if condition evaluates totrueIN- Process immediate content onlyWITHIN- Recursively process nested arrays/objects
DQL
OBJECT Transformation
TheOBJECT transformation expression creates a new object by evaluating name and value expressions for each element in a source array or object.
Syntax:
DQL
name_expr- Expression for field name (must evaluate tostring)value_expr- Expression for field value (field added only if notMISSING)name_var- Optional identifier holding the array index or field namevalue_var- Identifier holding the element valuesource- Expression evaluating to anARRAYorOBJECT- Returns
MISSINGif source isMISSING - Returns
NULLif source is any other non-array/object type
- Returns
condition- Optional filter; element included only if condition evaluates totrueIN- Process immediate content onlyWITHIN- Recursively process nested objects
DQL
Use Cases
Data Transformation:DQL
DQL
DQL
DQL
Array and Object Search Expressions
DQL provides search expressions that test whether elements in arrays or objects satisfy specified conditions. These are particularly useful inWHERE clauses to filter documents based on nested data.
Syntax
DQL
name_var- Optional identifier holding the array index (for arrays) or field name (for objects)value_var- Identifier holding the element valueexpression- Expression evaluating to anARRAYorOBJECT- Returns
MISSINGif expression evaluates toMISSING - Returns
NULLif expression evaluates to any other non-array/object type
- Returns
condition- Boolean expression tested against each elementIN- Search immediate content onlyWITHIN- Recursively search nested arrays/objects
ANY- Returnstrueif at least one element satisfies the condition (short-circuits on first match)EVERY- Returnstrueif all elements satisfy the condition (empty arrays/objects returntrue)ANY AND EVERY- LikeEVERYbut returnsfalsefor empty arrays/objects
Examples
Using ANY:DQL
DQL
DQL
IN vs WITHIN
The difference betweenIN and WITHIN is crucial:
IN - Direct Search:
DQL
DQL
Common Patterns
Filtering by Array Contents:DQL
DQL
DQL
DQL
Comparison Operators
The comparison operators fall into one of two sub-categories:- Missing value comparisons
- Regular value comparisons
- The presence of the field with a
NULLfor its value (as in SQL) - The absence of the field (which JSON permits)
NULL and UNKNOWN are synonym keywords and provide the same behavior.
If a field doesn’t exist in a document, any predicate using that field evaluates to MISSING (which is treated as false in WHERE clauses), except when using the IS MISSING or IS NOT MISSING operators which explicitly check for field existence.
| Operator | Purpose | Example |
|---|---|---|
| IS NULL | Returns true if the value is NULL, otherwise returns false | WHERE field_name IS NULL |
| IS NOT NULL | Returns true if the value is not NULL, otherwise returns false | WHERE field_name IS NOT NULL |
| IS MISSING | Returns true if the field is missing in a given document, otherwise returns false | WHERE field_name IS MISSING |
| IS NOT MISSING | Returns true if the field is not missing in a given document, otherwise returns false | WHERE field_name IS NOT MISSING |
| IS UNKNOWN | Returns true if the value is NULL, otherwise returns false | WHERE field_name IS UNKNOWN |
| IS NOT UNKNOWN | Returns true if the value is not NULL, otherwise returns false | WHERE field_name IS NOT UNKNOWN |
| = | Equality test | WHERE field_name = 100 |
| == | Equality test | WHERE field_name == 100 |
| != | Inequality test | WHERE field_name != 100 |
| <> | Inequality test | WHERE field_name <> 100 |
| < | Less than | WHERE field_name < 100 |
| > | Greater than | WHERE field_name > 100 |
| <= | Less than or equal to | WHERE field_name <= 100 |
| >= | Greater than or equal to | WHERE field_name >= 100 |
| BETWEEN | Inclusive range test. expr BETWEEN low AND high is equivalent to expr >= low AND expr <= high. Note that the order matters: BETWEEN 1 AND 10 and BETWEEN 10 AND 1 are not equivalent. Can be negated with NOT: expr NOT BETWEEN low AND high. | WHERE price BETWEEN 10 AND 100 |
Comparison Operations with NULL
In DQL,NULL represents missing or unknown data. It’s not a value in the way that 1 or 'text' are values. Any comparison operation that includes NULL will result in NULL.
| Equation | Result |
|---|---|
NULL = NULL | NULL |
NULL <> NULL | NULL |
1 = NULL | NULL |
1 > NULL | NULL |
Conditional Operators
Conditional Operators allow you to express conditional logic and handle NULL/MISSING values within your DQL queries.| Operator | Purpose | Example |
|---|---|---|
| coalesce(v1, v2, …) | Returns the first non-null, non-missing value or null if none exists. Synonym for ifmissingornull | WHERE coalesce(field_name_1, field_name_2, field_name_3) = 'foo' |
| decode(input, comp1, res1, [comp2, res2…] [, default value]) | Compares the input against each comp parameter, and if they match type and value, returns the corresponding res value. A NULL input matches a NULL res. If no matches are found, the default value is returned (which defaults to NULL). A MISSING input returns MISSING regardless | WHERE decode(field_name, 'foo', 'I found foo', 'bar', 'I found bar', 'I found nothing') = 'foo' |
| nvl(val, res1[, res2]) | If three arguments: returns res1 if val is not null and res2 otherwise. If two arguments: returns val if not null and res1 otherwise | WHERE nvl(field_name, 0) > 10 |
| isnull(v) | Returns true if v is null, otherwise false | WHERE isnull(field_name) |
| ismissing(v) | Returns true if v is missing, otherwise false | WHERE ismissing(field_name) |
| ismissingornull(v) | Returns true if v is missing or null, otherwise false | WHERE ismissingornull(field_name) |
| ifnull(v, v [, …]) | Returns the first v to not be null, otherwise null | WHERE ifnull(field1, field2, 'default') = 'default' |
| ifmissing(v, v [, …]) | Returns the first v to not be missing, otherwise null | WHERE ifmissing(field1, field2, 'default') = 'default' |
| ifmissingornull(v, v [, …]) | Returns the first v to not be missing or null. Synonym for coalesce | WHERE ifmissingornull(field1, field2, 'default') = 'default' |
| nullif(v1, v2) | Returns null if v1 equals v2, otherwise v1 or null if either is null or missing | WHERE nullif(field_name, 'ignore') IS NOT NULL |
| missingif(v1, v2) | Returns missing if v1 equals v2, otherwise v1 or missing if either is null or missing | WHERE missingif(field_name, 'ignore') IS NOT MISSING |
CASE Expressions
CASE expressions provide conditional logic similar to if-then-else constructs. DQL supports both simple and searched CASE expressions.Simple CASE
Compares an expression against multiple values:DQL
expression matches a value, the corresponding result is returned. If there is no match and there is no ELSE clause, the result is NULL. The first branch with a matching value is used.
Example:
DQL
Searched CASE
Evaluates multiple conditions:DQL
condition evaluates to true, the corresponding result is returned. If there is no match and there is no ELSE clause, the result is NULL. The first branch with a true condition is used.
Example:
DQL
Logical Operators
Logical operators perform logicalNOT, AND, and OR operations over Boolean values (TRUE and FALSE), plus NULL and MISSING.
| Operator | Purpose | Example |
|---|---|---|
| NOT | Returns true if the following condition is false, otherwise returns false. | WHERE NOT field_name = true |
| AND | Returns true if both branches are true, otherwise returns false | WHERE field_1 = true AND field_2 = false |
| OR | Returns true if one branch is true; otherwise, returns false | WHERE field_1 = true OR field_2 = false |
NOT Truth Table
| Value | Result |
|---|---|
| True | False |
| False | True |
| NULL | NULL |
AND Truth Table
| True | NULL | False | |
|---|---|---|---|
| True | True | NULL | False |
| NULL | NULL | NULL | False |
| False | False | False | False |
OR Truth Table
| True | NULL | False | |
|---|---|---|---|
| True | True | True | True |
| NULL | True | NULL | NULL |
| False | True | NULL | False |
Aggregate Functions
DQL provides aggregate functions that operate on groups of documents to produce summary values. For complete documentation on using aggregates with GROUP BY, see SELECT - Aggregate Functions.| Function | Purpose | Example |
|---|---|---|
| COUNT([DISTINCT] expr) | Counts items for which expr does not evaluate to NULL, MISSING, or FALSE. Use COUNT(*) to count all documents | SELECT COUNT(*) FROM cars |
| SUM([DISTINCT] expr) | Sums numeric values. Non-numeric values are silently ignored | SELECT SUM(price) FROM cars |
| AVG([DISTINCT] expr) | Returns the average of numeric values. Non-numeric values are silently ignored | SELECT AVG(mileage) FROM cars |
| MIN(expr) | Returns the minimum value. Values are compared according to Ditto type ordering rules | SELECT MIN(year) FROM cars |
| MAX(expr) | Returns the maximum value. Values are compared according to Ditto type ordering rules | SELECT MAX(year) FROM cars |
| MID([DISTINCT] expr) | Returns the arithmetic midpoint between MIN(expr) and MAX(expr), i.e. (min + max) / 2. Not the same as MEDIAN. Non-numeric values are silently ignored | SELECT MID(price) FROM cars |
| MEDIAN([DISTINCT] expr) | Returns the positional median value (the middle value when sorted). Non-numeric values are silently ignored | SELECT MEDIAN(price) FROM cars |
When
DISTINCT is specified, only distinct values are considered in the calculations. This requires maintaining a record of all distinct values encountered, which increases memory requirements for large result sets.Aggregate functions form a “dam” in the execution pipeline - all documents must be processed before results can be returned. This is different from non-aggregate queries which can stream results.
Miscellaneous Functions
| Function | Purpose | Example |
|---|---|---|
| request_info() | Returns an object with metadata about the active request: app_id, request_id, and start_time. Available in SDK 4.12 onwards. | SELECT request_info() FROM system:dual |