集約関数は、データベースの専門家が想定するとおり、通常の方法で動作します。
ClickHouse は、以下もサポートしています。
- パラメトリック集約関数: カラムに加えて、ほかのパラメータも受け取ります。
- コンビネータ: 集約関数の動作を変更します。
NULL の処理
集約では、NULL の argument はすべてスキップされます。集約 に複数の argument がある場合は、そのうち 1 つ以上が NULL である行は無視されます。
この規則には例外があります。関数 first_value、last_value と、それらの別名 (それぞれ any と anyLast) に modifier RESPECT NULLS が続く場合です。たとえば、FIRST_VALUE(b) RESPECT NULLS です。
例:
次の table を考えます。
┌─x─┬────y─┐
│ 1 │ 2 │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ 2 │
│ 3 │ 3 │
│ 3 │ ᴺᵁᴸᴸ │
└───┴──────┘たとえば、y カラムの値の合計を求めるとします。
SELECT sum(y) FROM t_null_big┌─sum(y)─┐
│ 7 │
└────────┘これで、groupArray 関数を使って y カラムから配列を作成できます。
SELECT groupArray(y) FROM t_null_big┌─groupArray(y)─┐
│ [2,2,3] │
└───────────────┘groupArray は、結果の配列に NULL を含めません。
COALESCE を使うと、NULL を用途に応じた適切な値に置き換えられます。たとえば avg(COALESCE(column, 0)) では、集約時にカラムの値を使用し、NULL の場合は 0 を使用します。
SELECT
avg(y),
avg(coalesce(y, 0))
FROM t_null_big┌─────────────avg(y)─┬─avg(coalesce(y, 0))─┐
│ 2.3333333333333335 │ 1.4 │
└────────────────────┴─────────────────────┘また、NULL のスキップ動作を回避するには、Tupleを使うこともできます。NULL値だけを含むTupleはNULLではないため、集約関数はそのNULL値があってもその行をスキップしません。
SELECT
groupArray(y),
groupArray(tuple(y)).1
FROM t_null_big;
┌カラムが集計関数の引数として使用される場合、集計はスキップされることに注意してください。たとえば、count は、パラメータなし (count()) または定数パラメータ付き (count(1)) の場合、ブロック内のすべての行をカウントします (引数に GROUP BY カラムが含まれないため、その値には依存しません) 。一方、count(column) は、column が NULL ではない行数のみを返します。
SELECT
v,
count(1),
count(v)
FROM
(
SELECT if(number < 10, NULL, number % 3) AS v
FROM numbers(15)
)
GROUP BY v
┌また、RESPECT NULLS を指定した first_value の例を以下に示します。この例では、NULL 入力がそのまま考慮されるため、NULL であるかどうかにかかわらず、最初に読み取られた値が返されることがわかります。
SELECT
col || '_' || ((col + 1) * 5 - 1) AS range,
first_value(odd_or_null) AS first,
first_value(odd_or_null) IGNORE NULLS as first_ignore_null,
first_value(odd_or_null) RESPECT NULLS as first_respect_nulls
FROM
(
SELECT
intDiv(number, 5) AS col,
if(number % 2 == 0, NULL, number) AS odd_or_null
FROM numbers(15)
)
GROUP BY col
ORDER BY col
┌