From eaf6b823dfb50e9b21a8df80706ed1924c69766a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 2 Mar 2026 15:31:36 +0000 Subject: [PATCH] minor doc fixes --- documentation/query/datatypes/array.md | 4 +- documentation/query/functions/aggregation.md | 15 + documentation/query/functions/array.md | 277 +++++++++++++++++++ 3 files changed, 295 insertions(+), 1 deletion(-) diff --git a/documentation/query/datatypes/array.md b/documentation/query/datatypes/array.md index 9f9bf7dc0..5cb4c71a7 100644 --- a/documentation/query/datatypes/array.md +++ b/documentation/query/datatypes/array.md @@ -308,7 +308,9 @@ SELECT ARRAY[1, NULL, 3] = ARRAY[1, NULL, 3] as with_nulls; ## Array functions Functions that operate on arrays are documented on a -[dedicated page](/docs/query/functions/array). There are also some +[dedicated page](/docs/query/functions/array), including +[element-wise aggregates](/docs/query/functions/array/#array_elem_min) that +work with `GROUP BY` and `SAMPLE BY`. There are also some [financial functions](/docs/query/functions/finance#l2price) that operate on arrays. diff --git a/documentation/query/functions/aggregation.md b/documentation/query/functions/aggregation.md index 7ce7cd0ac..28843745c 100644 --- a/documentation/query/functions/aggregation.md +++ b/documentation/query/functions/aggregation.md @@ -88,6 +88,21 @@ calculations. Functions are organized by category below. | [weighted_stddev_freq](#weighted_stddev_freq) | Weighted standard deviation (frequency weights) | | [weighted_stddev_rel](#weighted_stddev_rel) | Weighted standard deviation (reliability weights) | +### Array aggregates + +Several aggregates on this page ([first](#first), [first_not_null](#first_not_null), +[last](#last), [last_not_null](#last_not_null)) accept array columns directly. +For element-wise aggregation across arrays — summing, averaging, or finding +min/max position-by-position — see the +[array functions](/docs/query/functions/array/) page. + +| Function | Description | +| :------- | :---------- | +| [array_elem_avg](/docs/query/functions/array/#array_elem_avg) | Element-wise average across arrays | +| [array_elem_max](/docs/query/functions/array/#array_elem_max) | Element-wise maximum across arrays | +| [array_elem_min](/docs/query/functions/array/#array_elem_min) | Element-wise minimum across arrays | +| [array_elem_sum](/docs/query/functions/array/#array_elem_sum) | Element-wise sum across arrays | + --- QuestDB supports implicit `GROUP BY`. When aggregate functions are used with diff --git a/documentation/query/functions/array.md b/documentation/query/functions/array.md index 81a925d78..a18be1e30 100644 --- a/documentation/query/functions/array.md +++ b/documentation/query/functions/array.md @@ -229,6 +229,283 @@ SELECT array_cum_sum(ARRAY[ [1.0, 1.0], [2.0, 2.0] ]); | ---------------------- | | ARRAY[1.0,2.0,4.0,6.0] | +## array_elem_min + +`array_elem_min(array1, array2 [, ...])` or `array_elem_min(array)` returns an +array where each element is the minimum of the corresponding elements across the +inputs. Works in two modes: + +- **Multi-argument (per-row):** pass two or more `DOUBLE[]` expressions. The + function returns a single array that is the element-wise minimum of all + arguments. +- **Aggregate (GROUP BY / SAMPLE BY):** pass a single `DOUBLE[]` column. The + function aggregates across rows, returning one result array per group. + +`NULL` arrays are skipped entirely. `NULL` elements within an array are skipped +at that position. If every input at a given position is `NULL`, the result at +that position is `NULL`. + +When input arrays have different lengths, the output length is the maximum +across all inputs. Positions beyond the end of a shorter array receive no +contribution from that array. + +N-dimensional arrays are supported. The output shape is the per-dimension +maximum of all inputs. In multi-argument mode, all arguments must have the same +number of dimensions. + +#### Parameters + +**Multi-argument mode:** + +- `array1` — a `DOUBLE[]` array +- `array2` — a `DOUBLE[]` array +- `...` — additional `DOUBLE[]` arrays (optional) + +**Aggregate mode:** + +- `array` — a `DOUBLE[]` column + +#### Examples + +**Multi-argument — element-wise minimum of two arrays:** + +```questdb-sql +SELECT array_elem_min(ARRAY[1.0, 5.0, 3.0], ARRAY[4.0, 2.0, 6.0]); +``` + +| array_elem_min | +| --------------- | +| [1.0,2.0,3.0] | + +**Multi-argument — arrays of different lengths:** + +```questdb-sql +SELECT array_elem_min( + ARRAY[100.0, 200.0, 150.0], + ARRAY[120.0, 180.0, 160.0, 90.0] +); +``` + +| array_elem_min | +| --------------------------- | +| [100.0,180.0,150.0,90.0] | + +The fourth position has only one contributing value. + +**Multi-argument — NULL elements are skipped:** + +```questdb-sql +SELECT array_elem_min(ARRAY[100.0, null], ARRAY[null, 200.0]); +``` + +| array_elem_min | +| -------------- | +| [100.0,200.0] | + +Each position takes the minimum over the values that are present (1 value each +here, not 2). + +**Aggregate — worst bid prices per symbol each hour:** + +```questdb-sql +CREATE TABLE book ( + ts TIMESTAMP, symbol SYMBOL, bid_prices DOUBLE[] +) TIMESTAMP(ts) PARTITION BY DAY; + +INSERT INTO book VALUES + ('2025-06-01T09:30:00', 'AAPL', ARRAY[150.0, 149.5, 149.0]), + ('2025-06-01T09:30:05', 'AAPL', ARRAY[150.5, 149.0, 148.5, 148.0]), + ('2025-06-01T09:30:00', 'MSFT', ARRAY[420.0, 419.5]), + ('2025-06-01T09:30:05', 'MSFT', ARRAY[419.0, 418.5]); + +SELECT ts, symbol, array_elem_min(bid_prices) +FROM book +SAMPLE BY 1h; +``` + +| ts | symbol | array_elem_min | +| --------------------------- | ------ | -------------------------- | +| 2025-06-01T09:00:00.000000Z | AAPL | [150.0,149.0,148.5,148.0] | +| 2025-06-01T09:00:00.000000Z | MSFT | [419.0,418.5] | + +The `AAPL` group has snapshots with different book depths. The fourth position +only has one contributing row. + +**Multi-argument — 2D arrays:** + +```questdb-sql +SELECT array_elem_min( + ARRAY[[1.0, 8.0, 3.0], [5.0, 2.0, 9.0]], + ARRAY[[4.0, 6.0, 7.0], [3.0, 8.0, 1.0]] +); +``` + +| array_elem_min | +| ---------------------------------- | +| [[1.0,6.0,3.0],[3.0,2.0,1.0]] | + +## array_elem_max + +`array_elem_max(array1, array2 [, ...])` or `array_elem_max(array)` returns an +array where each element is the maximum of the corresponding elements across the +inputs. Works in both +[multi-argument and aggregate modes](#array_elem_min), with the same NULL handling, +different-length, and multi-dimensional behavior as `array_elem_min`. + +#### Parameters + +**Multi-argument mode:** + +- `array1`, `array2` [, `...`] — two or more `DOUBLE[]` arrays + +**Aggregate mode:** + +- `array` — a `DOUBLE[]` column + +#### Examples + +```questdb-sql +SELECT array_elem_max(ARRAY[1.0, 5.0, 3.0], ARRAY[4.0, 2.0, 6.0]); +``` + +| array_elem_max | +| --------------- | +| [4.0,5.0,6.0] | + +```questdb-sql +SELECT array_elem_max( + ARRAY[[1.0, 8.0, 3.0], [5.0, 2.0, 9.0]], + ARRAY[[4.0, 6.0, 7.0], [3.0, 8.0, 1.0]] +); +``` + +| array_elem_max | +| ---------------------------------- | +| [[4.0,8.0,7.0],[5.0,8.0,9.0]] | + +**Aggregate — best bid prices per symbol each hour:** + +Using the `book` table from the [array_elem_min](#array_elem_min) example: + +```questdb-sql +SELECT ts, symbol, array_elem_max(bid_prices) +FROM book +SAMPLE BY 1h; +``` + +| ts | symbol | array_elem_max | +| --------------------------- | ------ | -------------------------- | +| 2025-06-01T09:00:00.000000Z | AAPL | [150.5,149.5,149.0,148.0] | +| 2025-06-01T09:00:00.000000Z | MSFT | [420.0,419.5] | + +## array_elem_sum + +`array_elem_sum(array1, array2 [, ...])` or `array_elem_sum(array)` returns an +array where each element is the sum of the corresponding elements across the +inputs. Works in both +[multi-argument and aggregate modes](#array_elem_min), with the same NULL handling, +different-length, and multi-dimensional behavior as `array_elem_min`. + +Uses Kahan compensated summation to minimize floating-point rounding errors. + +#### Parameters + +**Multi-argument mode:** + +- `array1`, `array2` [, `...`] — two or more `DOUBLE[]` arrays + +**Aggregate mode:** + +- `array` — a `DOUBLE[]` column + +#### Examples + +```questdb-sql +SELECT array_elem_sum( + ARRAY[1.0, 2.0, 3.0], + ARRAY[10.0, 20.0, 30.0] +); +``` + +| array_elem_sum | +| ----------------- | +| [11.0,22.0,33.0] | + +**Aggregate — total filled quantities per level across a session:** + +```questdb-sql +CREATE TABLE fills ( + ts TIMESTAMP, symbol SYMBOL, fill_qtys DOUBLE[] +) TIMESTAMP(ts) PARTITION BY DAY; + +INSERT INTO fills VALUES + ('2025-06-01T09:30:00', 'AAPL', ARRAY[100.0, 200.0]), + ('2025-06-01T09:30:05', 'AAPL', ARRAY[150.0, 50.0]), + ('2025-06-01T09:30:10', 'AAPL', ARRAY[250.0, 300.0]); + +SELECT array_elem_sum(fill_qtys) FROM fills; +``` + +| array_elem_sum | +| --------------- | +| [500.0,550.0] | + +## array_elem_avg + +`array_elem_avg(array1, array2 [, ...])` or `array_elem_avg(array)` returns an +array where each element is the average of the corresponding elements across the +inputs. Works in both +[multi-argument and aggregate modes](#array_elem_min), with the same NULL handling, +different-length, and multi-dimensional behavior as `array_elem_min`. + +Uses Kahan compensated summation to minimize floating-point rounding errors. + +#### Parameters + +**Multi-argument mode:** + +- `array1`, `array2` [, `...`] — two or more `DOUBLE[]` arrays + +**Aggregate mode:** + +- `array` — a `DOUBLE[]` column + +#### Examples + +```questdb-sql +SELECT array_elem_avg(ARRAY[10.0, 20.0, 30.0], ARRAY[30.0, 40.0, 50.0]); +``` + +| array_elem_avg | +| ------------------ | +| [20.0,30.0,40.0] | + +**Aggregate — average bid sizes per symbol each hour:** + +```questdb-sql +CREATE TABLE book_sizes ( + ts TIMESTAMP, symbol SYMBOL, bid_sizes DOUBLE[] +) TIMESTAMP(ts) PARTITION BY DAY; + +INSERT INTO book_sizes VALUES + ('2025-06-01T09:30:00', 'AAPL', ARRAY[100.0, 200.0, 150.0]), + ('2025-06-01T09:30:05', 'AAPL', ARRAY[120.0, 180.0, 160.0, 90.0]), + ('2025-06-01T09:30:00', 'MSFT', ARRAY[500.0, 400.0]), + ('2025-06-01T09:30:05', 'MSFT', ARRAY[600.0, 300.0]); + +SELECT ts, symbol, array_elem_avg(bid_sizes) +FROM book_sizes +SAMPLE BY 1h; +``` + +| ts | symbol | array_elem_avg | +| --------------------------- | ------ | ------------------------ | +| 2025-06-01T09:00:00.000000Z | AAPL | [110.0,190.0,155.0,90.0] | +| 2025-06-01T09:00:00.000000Z | MSFT | [550.0,350.0] | + +The `AAPL` group has snapshots with different book depths. The fourth position +only has one contributing row. + ## array_max `array_max(array)` returns the maximum value from all the array elements. `NULL`