Операторы
Все операторы преобразуются в соответствующие функции на этапе парсинга запроса, с учётом их приоритетов и ассоциативности. Далее будут перечислены группы операторов в порядке их приоритета (чем выше, тем раньше оператор связывается со своими аргументами).
Операторы доступа
a[N] - доступ к элементу массива, функция arrayElement(a, N).
a.N - доступ к элементу кортежа, функция tupleElement(a, N).
Оператор числового отрицания
-a - функция negate(a).
Для чисел в кортеже также может быть использована tupleNegate.
Операторы умножения и деления
a * b - функция multiply(a, b)
Для умножения кортежа на число также может быть использована tupleMultiplyByNumber, для скалярного произведения: dotProduct.
a / b - функция divide(a, b)
Для деления кортежа на число также может быть использована tupleDivideByNumber.
a % b - функция modulo(a, b)
Операторы сложения и вычитания
a + b - функция plus(a, b)
Для сложения кортежей также может быть использована tuplePlus.
a - b - функция minus(a, b)
Для вычитания кортежей также может быть использована tupleMinus.
Операторы сравнения
a = b - функция equals(a, b)
a == b - функция equals(a, b)
a != b - функция notEquals(a, b)
a <> b - функция notEquals(a, b)
a <= b - функция lessOrEquals(a, b)
a >= b - функция greaterOrEquals(a, b)
a < b - функция less(a, b)
a > b - функция greater(a, b)
a LIKE s - функция like(a, b)
a NOT LIKE s - функция notLike(a, b)
a ILIKE s – функция ilike(a, b)
a BETWEEN b AND c - равнозначно a >= b AND a <= c
a NOT BETWEEN b AND c - равнозначно a < b OR a > c
Операторы для работы с множествами
Смотрите операторы IN и оператор EXISTS.
a IN ... - функция in(a, b)
a NOT IN ... - функция notIn(a, b)
a GLOBAL IN ... - функция globalIn(a, b)
a GLOBAL NOT IN ... - функция globalNotIn(a, b)
a = ANY (subquery) – функция in(a, subquery).
a != ANY (subquery) – равнозначно a NOT IN (SELECT singleValueOrNull(*) FROM subquery).
a = ALL (subquery) – равнозначно a IN (SELECT singleValueOrNull(*) FROM subquery).
a != ALL (subquery) – функция notIn(a, subquery).
Примеры
Запрос с ALL:
SELECT number AS a FROM numbers(10) WHERE a > ALL (SELECT number FROM numbers(3, 3));
Результат:
┌─a─┐
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘
Запрос с ANY:
SELECT number AS a FROM numbers(10) WHERE a > ANY (SELECT number FROM numbers(3, 3));
Результат:
┌─a─┐
│ 4 │
│ 5 │
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘
Оператор для работы с датами и временем
EXTRACT
EXTRACT(part FROM date);
Позволяет извлечь отдельные части из переданной даты. Например, можно получить месяц из даты, или минуты из времени.
В параметре part указывается, какой фрагмент даты нужно получить. Доступные значения:
DAY— День. Возможные значения: 1–31.MONTH— Номер месяца. Возможные значения: 1–12.YEAR— Год.SECOND— Секунда. Возможные значения: 0–59.MINUTE— Минута. Возможные значения: 0–59.HOUR— Час. Возможные значения: 0–23.
Эти значения могут быть указаны также в нижнем регистре (day, month).
В параметре date указывается исходная дата. Поддерживаются типы Date и DateTime.
Примеры:
SELECT EXTRACT(DAY FROM toDate('2017-06-15'));
SELECT EXTRACT(MONTH FROM toDate('2017-06-15'));
SELECT EXTRACT(YEAR FROM toDate('2017-06-15'));
В следующем примере создадим таблицу и добавим в неё значение с типом DateTime.
CREATE TABLE test.Orders
(
OrderId UInt64,
OrderName String,
OrderDate DateTime
)
ENGINE = Log;
INSERT INTO test.Orders VALUES (1, 'Jarlsberg Cheese', toDateTime('2008-10-11 13:23:44'));
SELECT
toYear(OrderDate) AS OrderYear,
toMonth(OrderDate) AS OrderMonth,
toDayOfMonth(OrderDate) AS OrderDay,
toHour(OrderDate) AS OrderHour,
toMinute(OrderDate) AS OrderMinute,
toSecond(OrderDate) AS OrderSecond
FROM test.Orders;
┌─OrderYear─┬─OrderMonth─┬─OrderDay─┬─OrderHour─┬─OrderMinute─┬─OrderSecond─┐
│ 2008 │ 10 │ 11 │ 13 │ 23 │ 44 │
└───────────┴────────────┴──────────┴───────────┴─────────────┴─────────────┘
Больше примеров приведено в тестах.
INTERVAL
Создаёт значение типа Interval которое должно использоваться в арифметических операциях со значениями типов Date и DateTime.
Типы интервалов:
SECONDMINUTEHOURDAYWEEKMONTHQUARTERYEAR
В качестве значения оператора INTERVAL вы можете также использовать строковый литерал. Например, выражение INTERVAL 1 HOUR идентично выражению INTERVAL '1 hour' или INTERVAL '1' hour.
Интервалы различных типов нельзя объединять. Нельзя использовать выражения вида INTERVAL 4 DAY 1 HOUR. Вместо этого интервалы можно выразить в единицах меньших или равных наименьшей единице интервала, Например, INTERVAL 25 HOUR. Также можно выполнять последовательные операции как показано в примере ниже.
Примеры:
SELECT now() AS current_date_time, current_date_time + INTERVAL 4 DAY + INTERVAL 3 HOUR;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:09:50 │ 2020-11-08 01:09:50 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4 day' + INTERVAL '3 hour';
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:12:10 │ 2020-11-08 01:12:10 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4' day + INTERVAL '3' hour;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay('4')), toIntervalHour('3'))─┐
│ 2020-11-03 22:33:19 │ 2020-11-08 01:33:19 │
└─────────────────────┴────────────────────────────────────────────────────────────┘
Вы можете изменить дату, не используя синтаксис INTERVAL, а просто добавив или отняв секунды, минуты и часы. Например, чтобы передвинуть дату на один день вперед, можно прибавить к ней значение 60*60*24.
Синтаксис INTERVAL или функция addDays предпочтительнее для работы с датами. Сложение с числом (например, синтаксис now() + ...) не учитывает региональные настройки времени, например, переход на летнее время.
Пример:
SELECT toDateTime('2014-10-26 00:00:00', 'Europe/Moscow') AS time, time + 60 * 60 * 24 AS time_plus_24_hours, time + toIntervalDay(1) AS time_plus_1_day;
┌────────────────time─┬──time_plus_24_hours─┬─────time_plus_1_day─┐
│ 2014-10-26 00:00:00 │ 2014-10-26 23:00:00 │ 2014-10-27 00:00:00 │
└─────────────────────┴─────────────────────┴─────────────────────┘
Смотрите также
- Тип данных Interval
- Функции преобразования типов toInterval
Оператор логического "И"
Синтаксис SELECT a AND b — вычисляет логическую конъюнкцию между a и b функцией and.
Оператор логического "ИЛИ"
Синтаксис SELECT a OR b — вычисляет логическую дизъюнкцию между a и b функцией or.
Оператор логического отрицания
Синтаксис SELECT NOT a — вычисляет логическое отрицание a функцией not.
Условный оператор
a ? b : c - функция if(a, b, c)
Примечание:
Условный оператор сначала вычисляет значения b и c, затем проверяет выполнение условия a, и только после этого возвращает соответствующее значение. Если в качестве b или с выступает функция arrayJoin(), то размножение каждой строки произойдет вне зависимости от условия а.
Условное выражение
CASE [x]
WHEN a THEN b
[WHEN ... THEN ...]
[ELSE c]
END
В случае указания x - функция transform(x, [a, ...], [b, ...], c). Иначе — multiIf(a, b, ..., c).
При отсутствии секции ELSE c, значением по умолчанию будет NULL.
Функция transform не умеет работать с NULL.
Оператор склеивания строк
s1 || s2 - функция concat(s1, s2)
Оператор создания лямбда-выражения
x -> expr - функция lambda(x, expr)
Следующие операторы не имеют приоритета, так как представляют собой скобки:
Оператор создания массива
[x1, ...] - функция array(x1, ...)
Оператор создания кортежа
(x1, x2, ...) - функция tuple(x2, x2, ...)
Ассоциативность
Все бинарные операторы имеют левую ассоциативность. Например, 1 + 2 + 3 преобразуется в plus(plus(1, 2), 3).
Иногда это работает не так, как ожидается. Например, SELECT 4 > 3 > 2 выдаст 0.
Для эффективности, реализованы функции and и or, принимающие произвольное количество аргументов. Соответствующие цепочки операторов AND и OR, преобразуются в один вызов этих функций.
Проверка на NULL
ClickHouse поддерживает операторы IS NULL и IS NOT NULL.
IS NULL
- Для значений типа Nullable оператор
IS NULLвозвращает:1, если значение —NULL.0в обратном случае.
- Для прочих значений оператор
IS NULLвсегда возвращает0.
Оператор можно оптимизировать, если включить настройку optimize_functions_to_subcolumns. При optimize_functions_to_subcolumns = 1 читается только подстолбец null вместо чтения и обработки данных всего столбца. Запрос SELECT n IS NULL FROM table преобразуется к запросу SELECT n.null FROM TABLE.
SELECT x+100 FROM t_null WHERE y IS NULL
┌─plus(x, 100)─┐
│ 101 │
└──────────────┘
IS NOT NULL
- Для значений типа Nullable оператор
IS NOT NULLвозвращает:0, если значение —NULL.1, в обратном случае.
- Для прочих значений оператор
IS NOT NULLвсегда возвращает1.
Оператор можно оптимизировать, если включить настройку optimize_functions_to_subcolumns. При optimize_functions_to_subcolumns = 1 читается только подстолбец null вместо чтения и обработки данных всего столбца. Запрос SELECT n IS NOT NULL FROM table преобразуется к запросу SELECT NOT n.null FROM TABLE.
SELECT * FROM t_null WHERE y IS NOT NULL
┌─x─┬─y─┐
│ 2 │ 3 │
└───┴───┘