Условные выражения

В этом разделе описываются SQL-совместимые условные выражения, имеющиеся в QHB.

Совет
Если вам требуется нечто, выходящее за пределы возможностей этих условных выражений, как вариант, попробуйте написать серверные функции на более выразительном языке программирования.

Примечание
Хотя COALESCE, GREATEST и LEAST синтаксически похожи на функции, они не являются обычными функциями и поэтому не могут использоваться с аргументами, в которых явно описан массив VARIADIC.


CASE

Выражение CASE в SQL является общим условным выражением, схожим с операторами if/else в других языках программирования:

CASE WHEN условие THEN результат
   [WHEN ...]
   [ELSE результат]
END

Предложения CASE можно использовать везде, где допускаются выражения. Каждое условие здесь — это выражение, возвращающее результат типа boolean. Если результат условия равен true, значением выражения CASE является результат, следующий за условием, а остальная часть выражения CASE не обрабатывается. Если результат условия не равен true, любые последующие предложения WHEN проверяются таким же образом. Если ни одно из условий WHEN не возвращает true, значением выражения CASE является результат предложения ELSE. Если предложение ELSE опущено и ни одно из условий не равно true, результат будет равен NULL.

Пример:

SELECT * FROM test;

 a
---
 1
 2
 3


SELECT a,
       CASE WHEN a=1 THEN 'one'
            WHEN a=2 THEN 'two'
            ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

Типы данных всех выражений результатов должны быть преобразованы в один выходной тип. Более подробную информацию см. в разделе UNION, CASE и связанные конструкции.

Существует «простая» форма выражения CASE, которая представляет собой вариант общей формы, описанной выше:

CASE выражение
    WHEN значение THEN результат
  [WHEN ...]
  [ELSE результат]
END

Первое выражение вычисляется, а затем сравнивается с каждым из выражений значение в предложениях WHEN, пока не будет найдено равное ему. Если совпадений не найдено, возвращается результат предложения ELSE (или значение NULL). Эта форма похожа на оператор switch в языке C.

Приведенный выше пример можно записать с простым синтаксисом CASE:

SELECT a,
       CASE a WHEN 1 THEN 'one'
              WHEN 2 THEN 'two'
              ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

Выражение CASE не вычисляет подвыражения, которые не нужны для определения результата. Например, таким способом возможно избежать ошибки деления на ноль:

SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;

Примечание
Как описано в разделе Правила вычисления выражений, существуют различные ситуации, в которых подвыражения выражения вычисляются в разное время, поэтому соблюдение принципа «CASE вычисляет только необходимые подвыражения» не гарантировано. Например, константное подвыражение 1/0 обычно приводит к ошибке деления на ноль во время планирования, даже если оно находится в ветви CASE, которая вовсе не задействуется во время выполнения.


COALESCE

COALESCE(значение [, ...])

Функция COALESCE возвращает первый же из своих аргументов, отличный от NULL. NULL возвращается, только если все аргументы равны NULL. Эта функция часто используется для замены значения по умолчанию значениями NULL при извлечении данных для отображения, например:

SELECT COALESCE(description, short_description, '(none)') ...

Этот запрос возвращает description, если оно не равно NULL, либо short_description, если оно не равно NULL, либо (none), если они оба равны NULL.

Все аргументы должны быть приводимыми к одному общему типу данных, который и будет типом результата (подробную информацию см. в разделе UNION, CASE и связанные конструкции).

Как и выражение CASE, COALESCE вычисляет только аргументы, которые необходимы для определения результата; то есть аргументы справа от первого отличного от NULL аргумента не вычисляются. Эта соответствующая стандарту SQL функция предоставляет возможности, схожие с таковыми NVL и IFNULL, использующихся в некоторых других СУБД.


NULLIF

NULLIF(значение1, значение2)

Функция NULLIF возвращает значение NULL, если значение1 равно значению2; в противном случае она возвращает значение1. Это можно использовать для выполнения операции, обратной той, что показана в приведенном выше примере COALESCE:

SELECT NULLIF(value, ’(none)’) ...

В этом примере если value равно (none), возвращается NULL, в противном случае возвращается значение value.

Два аргумента этой функции должны быть сравнимых типов. Если говорить конкретнее, они сравниваются точно так же, как в записи значение1 = значение2, поэтому для этих типов должен иметься подходящий оператор =.

Результат имеет тот же тип, что и первый аргумент — но есть одна тонкость. Фактически возвращается первый аргумент подразумеваемого оператора =, и в некоторых случаях он преобразуется, чтобы соответствовать типу второго аргумента. К примеру, NULLIF(1, 2.2) выдает numeric, поскольку оператора integer = numeric не существует, есть лишь оператор numeric = numeric.


GREATEST и LEAST

GREATEST(значение [, ...])
LEAST(значение [, ...])

Функции GREATEST и LEAST выбирают наибольшее или наименьшее значение из списка с любым числом выражений. Все выражения должны быть преобразуемыми в общий тип данных, который и будет типом результата (подробную информацию см. в разделе UNION, CASE и связанные конструкции). Значения NULL в списке игнорируются. Результатом будет NULL, только если все выражения вычисляются как равные NULL.

Обратите внимание, что GREATEST и LEAST не входят в стандарт SQL, но относятся к распространенным расширениям. В некоторых другие базах данных они возвращают NULL, если любой из аргументов равен NULL, а не только когда все аргументы равны NULL.