Функции по работе с массивами ============================= ### empty Возвращает 1 для пустого массива, и 0 для непустого массива. Тип результата - UInt8. Функция также работает для строк. ### notEmpty Возвращает 0 для пустого массива, и 1 для непустого массива. Тип результата - UInt8. Функция также работает для строк. ### length Возвращает количество элементов в массиве. Тип результата - UInt64. Функция также работает для строк. ### emptyArrayUInt8, emptyArrayUInt16, emptyArrayUInt32, emptyArrayUInt64 ### emptyArrayInt8, emptyArrayInt16, emptyArrayInt32, emptyArrayInt64 ### emptyArrayFloat32, emptyArrayFloat64 ### emptyArrayDate, emptyArrayDateTime ### emptyArrayString Принимает ноль аргументов и возвращает пустой массив соответствующего типа. ### emptyArrayToSingle Принимает пустой массив и возвращает массив из одного элемента, равного значению по умолчанию. ### range(N) Возвращает массив чисел от 0 до N-1. На всякий случай, если на блок данных, создаются массивы суммарной длины больше 100 000 000 элементов, то кидается исключение. ### array(x1, ...), оператор \[x1, ...\] Создаёт массив из аргументов функции. Аргументы должны быть константами и иметь типы, для которых есть наименьший общий тип. Должен быть передан хотя бы один аргумент, так как иначе непонятно, какого типа создавать массив. То есть, с помощью этой функции невозможно создать пустой массив (для этого используйте функции emptyArray\*, описанные выше). Возвращает результат типа Array(T), где T - наименьший общий тип от переданных аргументов. ### arrayElement(arr, n), оператор arr\[n\] Достаёт элемент с индексом n из массива arr. n должен быть любым целочисленным типом. Индексы в массиве начинаются с единицы. Поддерживаются отрицательные индексы - в этом случае, будет выбран соответствующий по номеру элемент с конца. Например, arr\[-1\] - последний элемент массива. Если индекс выходит за границы массива, то возвращается некоторое значение по умолчанию (0 для чисел, пустая строка для строк и т. п.). ### has(arr, elem) Проверяет наличие элемента elem в массиве arr. Возвращает 0, если элемента в массиве нет, или 1, если есть. ### indexOf(arr, x) Возвращает индекс элемента x (начиная с 1), если он есть в массиве, или 0, если его нет. ### countEqual(arr, x) Возвращает количество элементов массива, равных x. Эквивалентно arrayCount(elem -> elem = x, arr). ### arrayEnumerate(arr) Возвращает массив \[1, 2, 3, ..., length(arr)\] Эта функция обычно используется совместно с ARRAY JOIN. Она позволяет, после применения ARRAY JOIN, посчитать что-либо только один раз для каждого массива. Пример: ```sql SELECT count() AS Reaches, countIf(num = 1) AS Hits FROM test.hits ARRAY JOIN GoalsReached, arrayEnumerate(GoalsReached) AS num WHERE CounterID = 160656 LIMIT 10 ``` ```text ┌─Reaches─┬──Hits─┐ │ 95606 │ 31406 │ └─────────┴───────┘ ``` В этом примере, Reaches - число достижений целей (строк, получившихся после применения ARRAY JOIN), а Hits - число хитов (строк, которые были до ARRAY JOIN). В данном случае, тот же результат можно получить проще: ```sql SELECT sum(length(GoalsReached)) AS Reaches, count() AS Hits FROM test.hits WHERE (CounterID = 160656) AND notEmpty(GoalsReached) ``` ```text ┌─Reaches─┬──Hits─┐ │ 95606 │ 31406 │ └─────────┴───────┘ ``` Также эта функция может быть использована в функциях высшего порядка. Например, с её помощью можно достать индексы массива для элементов, удовлетворяющих некоторому условию. ### arrayEnumerateUniq(arr, ...) Возвращает массив, такого же размера, как исходный, где для каждого элемента указано, какой он по счету среди элементов с таким же значением. Например: arrayEnumerateUniq(\[10, 20, 10, 30\]) = \[1, 1, 2, 1\]. Эта функция полезна при использовании ARRAY JOIN и агрегации по элементам массива. Пример: ```sql SELECT Goals.ID AS GoalID, sum(Sign) AS Reaches, sumIf(Sign, num = 1) AS Visits FROM test.visits ARRAY JOIN Goals, arrayEnumerateUniq(Goals.ID) AS num WHERE CounterID = 160656 GROUP BY GoalID ORDER BY Reaches DESC LIMIT 10 ``` ```text ┌──GoalID─┬─Reaches─┬─Visits─┐ │ 53225 │ 3214 │ 1097 │ │ 2825062 │ 3188 │ 1097 │ │ 56600 │ 2803 │ 488 │ │ 1989037 │ 2401 │ 365 │ │ 2830064 │ 2396 │ 910 │ │ 1113562 │ 2372 │ 373 │ │ 3270895 │ 2262 │ 812 │ │ 1084657 │ 2262 │ 345 │ │ 56599 │ 2260 │ 799 │ │ 3271094 │ 2256 │ 812 │ └─────────┴─────────┴────────┘ ``` В этом примере, для каждого идентификатора цели, посчитано количество достижений целей (каждый элемент вложенной структуры данных Goals является достижением целей) и количество визитов. Если бы не было ARRAY JOIN, мы бы считали количество визитов как sum(Sign). Но в данном случае, строчки были размножены по вложенной структуре Goals, и чтобы после этого учесть каждый визит один раз, мы поставили условие на значение функции arrayEnumerateUniq(Goals.ID). Функция arrayEnumerateUniq может принимать несколько аргументов - массивов одинаковых размеров. В этом случае, уникальность считается для кортежей элементов на одинаковых позициях всех массивов. ```sql SELECT arrayEnumerateUniq([1, 1, 1, 2, 2, 2], [1, 1, 2, 1, 1, 2]) AS res ``` ```text ┌─res───────────┐ │ [1,2,1,1,2,1] │ └───────────────┘ ``` Это нужно при использовании ARRAY JOIN с вложенной структурой данных и затем агрегации по нескольким элементам этой структуры. ### arrayUniq(arr, ...) Если передан один аргумент, считает количество разных элементов в массиве. Если передано несколько аргументов, считает количество разных кортежей из элементов на соответствующих позициях в нескольких массивах. Если необходимо получить список уникальных элементов массива, можно воспользоваться arrayReduce('groupUniqArray', arr). ### arrayJoin(arr) Особенная функция. Смотрите раздел "Функция arrayJoin".