9.18. Условные выражения #
В этом разделе описаны SQL-совместимые условные выражения, которые поддерживаются в Postgres Pro.
Подсказка
Если возможностей этих условных выражений оказывается недостаточно, вероятно, имеет смысл перейти к написанию серверных функций на более мощном языке программирования.
Примечание
Хотя конструкции COALESCE
, GREATEST
и LEAST
синтаксически похожи на функции, они не являются обычными функциями, и поэтому им нельзя передать в аргументах явно описанный массив VARIADIC
.
9.18.1. CASE
#
Выражение CASE
в SQL представляет собой общее условное выражение, напоминающее операторы if/else в других языках программирования:
CASE WHENусловие
THENрезультат
[WHEN ...] [ELSEрезультат
] END
Предложения CASE
можно использовать везде, где допускаются выражения. Каждое условие
в нём представляет собой выражение, возвращающее результат типа boolean
. Если результатом выражения оказывается true, значением выражения CASE
становится результат
, следующий за условием, а остальная часть выражения CASE
не вычисляется. Если же условие не выполняется, за ним таким же образом проверяются все последующие предложения WHEN
. Если не выполняется ни одно из условий
WHEN
, значением CASE
становится результат
, записанный в предложении ELSE
. Если при этом предложение ELSE
отсутствует, результатом выражения будет 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
Типы данных всех выражений результатов
должны приводиться к одному выходному типу. Подробнее это описано в Разделе 10.5.
Существует также «простая» форма выражения 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;
Примечание
Как было описано в Подразделе 4.2.14, всё же возможны ситуации, когда подвыражения вычисляются на разных этапах, так что железной гарантии, что в «CASE
вычисляются только необходимые подвыражения», в принципе нет. Например, константное подвыражение 1/0
обычно вызывает ошибку деления на ноль на этапе планирования, хотя эта ветвь CASE
может вовсе не вычисляться во время выполнения.
9.18.2. COALESCE
#
COALESCE
(значение
[, ...])
Функция COALESCE
возвращает первый попавшийся аргумент, отличный от NULL. Если же все аргументы равны NULL, результатом тоже будет NULL. Это часто используется при отображении данных для подстановки некоторого значения по умолчанию вместо значений NULL:
SELECT COALESCE(description, short_description, '(none)') ...
Этот запрос вернёт значение description
, если оно не равно NULL, либо short_description
, если оно не NULL, и строку (none)
, если оба эти значения равны NULL.
Аргументы должны быть приводимыми к одному общему типу, который и будет типом результата (подробнее об этом говорится в Разделе 10.5).
Как и выражение CASE
, COALESCE
вычисляет только те аргументы, которые необходимы для получения результата; то есть, аргументы правее первого отличного от NULL аргумента не вычисляются. Эта функция соответствует стандарту SQL, а в некоторых других СУБД её аналоги называются NVL
и IFNULL
.
9.18.3. 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
.
9.18.4. GREATEST
и LEAST
#
GREATEST
(значение
[, ...])
LEAST
(значение
[, ...])
Функции GREATEST
и LEAST
выбирают наибольшее или наименьшее значение из списка выражений. Все эти выражения должны приводиться к общему типу данных, который станет типом результата (подробнее об этом в Разделе 10.5).
Значения NULL в этом списке игнорируются, так что результат выражения будет равен NULL, только если все его аргументы равны NULL. (Это отклонение от стандарта SQL. Согласно стандарту, возвращается значение NULL, если какой-либо аргумент равен NULL. Подобным образом ведут себя и некоторые другие базы данных.)