Условные функции
if
Выполняет условную ветвление.
Если условие cond
оценивается в ненулевое значение, функция возвращает результат выражения then
. Если cond
оценивается в ноль или NULL
, то возвращается результат выражения else
.
Настройка short_circuit_function_evaluation управляет тем, используется ли краткая оценка. Если включена, выражение then
оценивалось только для строк, где cond
равно true
, а выражение else
- для строк, где cond
равно false
. Например, при краткой оценке исключение деления на ноль не выбрасывается при выполнении запроса SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10)
.
then
и else
должны быть похожими по типу.
Синтаксис
Псевдоним: cond ? then : else
(тернарный оператор)
Аргументы
cond
– Оцениваемое условие. UInt8, Nullable(UInt8) или NULL.then
– Выражение, возвращаемое, еслиcondition
истинно.else
– Выражение, возвращаемое, еслиcondition
ложно или NULL.
Возвращаемые значения
Результат любого из выражений then
или else
, в зависимости от условия cond
.
Пример
Результат:
multiIf
Позволяет записывать оператор CASE компактнее в запросе.
Синтаксис
Настройка short_circuit_function_evaluation управляет тем, используется ли краткая оценка. Если включена, выражение then_i
оценивается только для строк, где ((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}) AND cond_i)
равно true
, cond_i
будет оцениваться только для строк, где ((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}))
равно true
. Например, при краткой оценке исключение деления на ноль не выбрасывается при выполнении запроса SELECT multiIf(number = 2, intDiv(1, number), number = 5) FROM numbers(10)
.
Аргументы
Функция принимает 2N+1
параметров:
cond_N
— N-е оцениваемое условие, которое управляет тем, будет ли возвращеноthen_N
.then_N
— Результат функции, когдаcond_N
истинно.else
— Результат функции, если ни одно из условий не истинно.
Возвращаемые значения
Результат любого из выражений then_N
или else
, в зависимости от условий cond_N
.
Пример
Предположим, есть такая таблица:
Использование условных результатов напрямую
Условные функции всегда возвращают 0
, 1
или NULL
. Поэтому вы можете использовать условные результаты напрямую вот так:
NULL-значения в условных функциях
Когда в условных выражениях участвуют значения NULL
, результат также будет NULL
.
Поэтому вам следует осторожно составлять свои запросы, если типы являются Nullable
.
Следующий пример демонстрирует это, не добавляя условие равенства в multiIf
.
greatest
Возвращает наибольшее значение из списка значений. Все члены списка должны быть сопоставимыми по типу.
Примеры:
Возвращаемый тип - Float64, так как UInt8 должен быть повышен до 64 бит для сравнения.
Возвращаемый тип - DateTime64, так как DateTime32 должен быть повышен до 64 бит для сравнения.
least
Возвращает наименьшее значение из списка значений. Все члены списка должны быть сопоставимыми по типу.
Примеры:
Возвращаемый тип - Float64, так как UInt8 должен быть повышен до 64 бит для сравнения.
Возвращаемый тип - DateTime64, так как DateTime32 должен быть повышен до 64 бит для сравнения.
clamp
Ограничивает возвращаемое значение между A и B.
Синтаксис
Аргументы
value
– Входное значение.min
– Ограничение нижней границы.max
– Ограничение верхней границы.
Возвращаемые значения
Если значение меньше минимального, возвращается минимальное значение; если больше максимального, возвращается максимальное значение; в противном случае возвращается текущее значение.
Примеры:
Оператор CASE
Выражение CASE в ClickHouse предоставляет условную логику, аналогичную оператору SQL CASE. Оно оценивает условия и возвращает значения на основе первого совпадающего условия.
ClickHouse поддерживает две формы CASE:
CASE WHEN ... THEN ... ELSE ... END
Эта форма позволяет полную гибкость и реализуется внутри с помощью функции multiIf. Каждое условие оценивается независимо, и выражения могут включать не константные значения.
CASE <expr> WHEN <val1> THEN ... WHEN <val2> THEN ... ELSE ... END
Эта более компактная форма оптимизирована для сопоставления значений констант и использует caseWithExpression()
внутри.
Например, следующее является допустимым:
Эта форма также не требует, чтобы возвращаемые выражения были константами.
Замечания
ClickHouse определяет тип результата выражения CASE (или его внутреннего эквивалента, например multiIf
) до оценки любых условий. Это важно, когда возвращаемые выражения отличаются по типу, например, разные временные зоны или числовые типы.
- Тип результата выбирается на основе наибольшего совместимого типа среди всех ветвей.
- После выбора этого типа все другие ветви неявно приводятся к нему - даже если их логика никогда не будет выполнена во время выполнения.
- Для типов, таких как DateTime64, где временная зона является частью сигнатуры типа, это может привести к неожиданному поведению: первая встреченная временная зона может быть использована для всех ветвей, даже если другие ветви указывают на разные временные зоны.
Например, ниже все строки возвращают временную метку в часовом поясе первой соответствующей ветви, т.е. Asia/Kolkata
Здесь ClickHouse видит несколько типов DateTime64(3, <timezone>)
. Он выводит общий тип как DateTime64(3, 'Asia/Kolkata'
, так как это первый, который он видит, неявно приводя другие ветви к этому типу.
Это можно решить, преобразовав в строку, чтобы сохранить предполагаемое форматирование временной зоны: