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

CASE#

Стандартное SQL-выражение CASE имеет две формы. “Простая” форма проверяет каждое выражение value слева направо, пока не найдет то, которое равно expression:

CASE expression
    WHEN value THEN result
    [ WHEN ... ]
    [ ELSE result ]
END

Возвращается result для совпавшего value. Если совпадение не найдено, возвращается result из блока ELSE, если он есть; в противном случае возвращается null. Пример:

SELECT a,
       CASE a
           WHEN 1 THEN 'one'
           WHEN 2 THEN 'two'
           ELSE 'many'
       END

“Поисковая” форма вычисляет каждое логическое condition слева направо, пока одно из них не станет истинным, и возвращает соответствующий result:

CASE
    WHEN condition THEN result
    [ WHEN ... ]
    [ ELSE result ]
END

Если ни одно условие не истинно, возвращается result из блока ELSE, если он есть; в противном случае возвращается null. Пример:

SELECT a, b,
       CASE
           WHEN a = 1 THEN 'aaa'
           WHEN b = 2 THEN 'bbb'
           ELSE 'ccc'
       END

SQL UDF могут использовать CASE statements, синтаксис которых немного отличается от CASE-выражений. В частности, обратите внимание на требование завершать каждый блок точкой с запятой ; и на использование END CASE.

IF#

Выражение IF имеет две формы: одна принимает только true_value, а другая принимает и true_value, и false_value:

if(condition, true_value)#

Вычисляет и возвращает true_value, если condition истинно; иначе возвращается null, и true_value не вычисляется.

if(condition, true_value, false_value)

Вычисляет и возвращает true_value, если condition истинно; иначе вычисляет и возвращает false_value.

Следующие выражения IF и CASE эквивалентны:

SELECT
  orderkey,
  totalprice,
  IF(totalprice >= 150000, 'High Value', 'Low Value')
FROM tpch.sf1.orders;
SELECT
  orderkey,
  totalprice,
  CASE
    WHEN totalprice >= 150000 THEN 'High Value'
    ELSE 'Low Value'
  END
FROM tpch.sf1.orders;

SQL UDF могут использовать IF statements, синтаксис которых немного отличается от выражений IF. В частности, обратите внимание на требование завершать каждый блок точкой с запятой ; и на использование END IF.

COALESCE#

coalesce(value1, value2[, ...])#

Возвращает первое ненулевое value в списке аргументов. Как и в выражении CASE, аргументы вычисляются только при необходимости.

NULLIF#

nullif(value1, value2)#

Возвращает null, если value1 равно value2; иначе возвращает value1.

TRY#

try(expression)#

Вычисляет выражение и обрабатывает определенные типы ошибок, возвращая NULL.

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

TRY обрабатывает следующие ошибки:

  • Деление на ноль

  • Неверное приведение типа или аргумент функции

  • Числовое значение вне диапазона

Examples#

Исходная таблица с некорректными данными:

SELECT * FROM shipping;
 origin_state | origin_zip | packages | total_cost
--------------+------------+----------+------------
 California   |      94131 |       25 |        100
 California   |      P332a |        5 |         72
 California   |      94025 |        0 |        155
 New Jersey   |      08544 |      225 |        490
(4 rows)

Ошибка запроса без TRY:

SELECT CAST(origin_zip AS BIGINT) FROM shipping;
Query failed: Cannot cast 'P332a' to BIGINT

Значения NULL с TRY:

SELECT TRY(CAST(origin_zip AS BIGINT)) FROM shipping;
 origin_zip
------------
      94131
 NULL
      94025
      08544
(4 rows)

Ошибка запроса без TRY:

SELECT total_cost / packages AS per_package FROM shipping;
Query failed: Division by zero

Значения по умолчанию с TRY и COALESCE:

SELECT COALESCE(TRY(total_cost / packages), 0) AS per_package FROM shipping;
 per_package
-------------
          4
         14
          0
         19
(4 rows)