Условные функции
Обзор
Непосредственное использование результатов условных выражений
Условные выражения всегда возвращают 0, 1 или NULL. Поэтому вы можете непосредственно использовать результаты условных выражений, как в этом примере:
Значения NULL в условных выражениях
Если в условных выражениях участвуют значения NULL, результат также будет NULL.
Поэтому при работе с типами Nullable следует тщательно составлять запросы.
Следующий пример демонстрирует это на неудачной попытке добавить условие равенства к multiIf.
Оператор CASE
Выражение CASE в ClickHouse предоставляет условную логику, аналогичную оператору CASE в SQL. Оно проверяет условия и возвращает значения на основе первого истинного условия.
ClickHouse поддерживает две формы CASE:
CASE WHEN ... THEN ... ELSE ... END
Эта форма обеспечивает полную гибкость и внутренне реализована с использованием функции multiIf. Каждое условие вычисляется независимо, и выражения могут включать неконстантные значения.
CASE <expr> WHEN <val1> THEN ... WHEN <val2> THEN ... ELSE ... END
Эта более компактная форма оптимизирована для сопоставления с константными значениями и внутри используетcaseWithExpression().
Например, следующее выражение является корректным:
┌─number─┬─result─┐ │ 0 │ 100 │ │ 1 │ 200 │ │ 2 │ 0 │ └────────┴────────┘
3 строк в наборе. Прошло: 0.002 сек.
Ограничения
ClickHouse определяет результирующий тип выражения CASE (или его внутреннего аналога, такого как multiIf) до вычисления каких‑либо условий. Это важно, когда возвращаемые выражения различаются по типу, например используют разные часовые пояса или числовые типы.
- Результирующий тип выбирается как наиболее общий совместимый тип среди всех ветвей.
- После выбора этого типа все остальные ветви неявно приводятся к нему — даже если их логика никогда не будет выполнена во время выполнения.
- Для типов вроде DateTime64, где часовой пояс является частью сигнатуры типа, это может приводить к неожиданному поведению: первый встреченный часовой пояс может использоваться для всех ветвей, даже если в других ветвях указаны другие часовые пояса.
Например, в приведённом ниже случае во всех строках будет возвращаться метка времени в часовом поясе первой совпавшей ветви, то есть Asia/Kolkata.
Здесь ClickHouse видит несколько возвращаемых типов DateTime64(3, <timezone>). Он выводит общий тип как DateTime64(3, 'Asia/Kolkata' по первому встретившемуся варианту, неявно приводя остальные ветви к этому типу.
Эту проблему можно решить, преобразовав значение в строку, чтобы сохранить задуманное форматирование часового пояса:
┌─number─┬─tz──────────────────┐ │ 0 │ 1970-01-01 05:30:00 │ │ 1 │ 1969-12-31 16:00:00 │ │ 2 │ 1970-01-01 00:00:00 │ └────────┴─────────────────────┘
3 строки в наборе. Прошло: 0.002 сек.
clamp
Введена в версии: v24.5
Ограничивает значение заданными минимальной и максимальной границами.
Если значение меньше минимума, возвращается минимум. Если значение больше максимума, возвращается максимум. В противном случае возвращается само значение.
Все аргументы должны быть сравнимых типов. Тип результата — наибольший совместимый тип среди всех аргументов.
Синтаксис
Аргументы
value— Значение, которое нужно ограничить. -min— Нижняя граница. -max— Верхняя граница.
Возвращаемое значение
Возвращает значение, ограниченное диапазоном [min, max].
Примеры
Базовый пример использования
Значение меньше минимального
Значение превышает максимум
greatest
Введена в версии: v1.1
Возвращает наибольшее значение среди аргументов.
Аргументы NULL игнорируются.
- Для массивов возвращает лексикографически наибольший массив.
- Для типов
DateTimeтип результата продвигается до наиболее «широкого» типа (например, доDateTime64, если он смешан сDateTime32).
least_greatest_legacy_null_behavior для изменения поведения NULLВерсия 24.12 внесла изменение, несовместимое с предыдущими версиями: значения NULL игнорируются, тогда как ранее возвращалось NULL, если один из аргументов был NULL.
Чтобы сохранить прежнее поведение, установите настройку least_greatest_legacy_null_behavior (по умолчанию: false) в значение true.
Синтаксис
Аргументы
x1[, x2, ...]— Одного или нескольких значений для сравнения. Все аргументы должны иметь сопоставимые типы.Any
Возвращаемое значение
Возвращает наибольшее значение среди аргументов, приведённое к наибольшему совместимому типу. Any
Примеры
Числовые типы
Массивы
Типы данных DateTime
if
Впервые появилась в версии v1.1
Выполняет условное ветвление.
- Если условие
condпринимает ненулевое значение, функция возвращает результат выраженияthen. - Если
condравно нулю или NULL, возвращается результат выраженияelse.
Настройка short_circuit_function_evaluation определяет, используется ли укороченное вычисление выражений (short-circuit evaluation).
Если настройка включена, выражение then вычисляется только для строк, где cond истинно, а выражение else — только для строк, где cond ложно.
Например, при укороченном вычислении выражений при выполнении следующего запроса не возникает исключения «деление на ноль»:
then и else должны быть одного типа.
Синтаксис
Аргументы
cond— вычисляемое условие.UInt8илиNullable(UInt8)илиNULLthen— выражение, возвращаемое, еслиcondистинно.else— выражение, возвращаемое, еслиcondложно или равноNULL.
Возвращаемое значение
Результат выражения then или else в зависимости от значения cond.
Примеры
Пример использования
least
Впервые появилось в версии v1.1
Возвращает наименьшее значение среди аргументов.
Аргументы NULL игнорируются.
- Для массивов возвращает лексикографически наименьший массив.
- Для типов DateTime тип результата повышается до наибольшего типа (например, DateTime64 при смешивании с DateTime32).
least_greatest_legacy_null_behavior для изменения поведения NULLВерсия 24.12 внесла несовместимое с предыдущими версиями изменение, в результате которого значения NULL игнорируются, тогда как ранее возвращалось NULL, если один из аргументов был NULL.
Чтобы сохранить прежнее поведение, установите настройку least_greatest_legacy_null_behavior (по умолчанию: false) в значение true.
Синтаксис
Аргументы
x1[, x2, ...]— Одно значение или несколько значений для сравнения. Все аргументы должны быть сравнимых типов.Any
Возвращаемое значение
Возвращает наименьшее значение среди аргументов, приведённое к наибольшему совместимому типу. Any
Примеры
Числовые типы
Массивы
Типы данных DateTime
multiIf
Добавлена в версии: v1.1
Позволяет более компактно записывать оператор CASE в запросе.
Последовательно вычисляет каждое условие. Для первого условия, которое истинно (ненулевое и не NULL), возвращает соответствующее значение ветки.
Если ни одно из условий не истинно, возвращается значение else.
Настройка short_circuit_function_evaluation управляет тем,
используется ли укороченное вычисление. Если оно включено, выражение then_i вычисляется только для строк, для которых
((NOT cond_1) AND ... AND (NOT cond_{i-1}) AND cond_i) истинно.
Например, при укороченном вычислении при выполнении следующего запроса не возникает исключения деления на ноль:
Все выражения ветвей и else должны иметь общий супертип. Условия, результатом которых является NULL, считаются ложными.
Синтаксис
Псевдонимы: caseWithoutExpression, caseWithoutExpr
Аргументы
cond_N— N‑е вычисляемое условие, которое определяет, будет ли возвращено значениеthen_N.UInt8илиNullable(UInt8)илиNULLthen_N— Результат функции, когдаcond_Nистинно. -else— Результат функции, если ни одно из условий не истинно.
Возвращаемое значение
Возвращает результат then_N для соответствующего cond_N, иначе возвращает значение из else.
Примеры
Пример использования