Условные функции
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'
как первый, который он видит, неявно приводя другие ветви к этому типу.
Это можно исправить, преобразовав в строку, чтобы сохранить предполагаемое форматирование часового пояса: