Иллюстрированный самоучитель по PostgreSQL

Конструкции CASE

Чтобы программа SQL могла принимать простейшие решения, не прибегая к процедурным языкам, в PostgreSQL поддерживаются конструкции CASE, предусмотренные стандартом SQL Ключевые слова SQL CASE, WHEN, THEN и END позволяют выполнять простые условные преобразования записей.

Вся конструкция CASE включается в целевой список команды SELECT. По умолчанию итоговому полю конструкции CASE присваивается имя case, но ему можно назначить синоним, как любому обычному полю. Общий синтаксис конструкции CASE в списке целей команды SELECT выглядит следующим образом:

CASE WHEN условие! THEN результат! WHEN условие2 THEN результат2
[… ]
[ ELSE результат_по_умопчанию END [ AS синоним ]

Конструкция CASE-WHEN-THEN-ELSE отчасти напоминает условные команды if-then-else в традиционных языках программирования (листинг 4.50). Условия секций WHEN должны возвращать логический результат.

Если условие в секции WHEN выполняется, результат соответствующей секции THEN возвращается в поле итогового набора. Если ни одно условие не выполнено, можно задать значение по умолчанию в секции ELSE. Если при отсутствии секции ELSE результат остается неопределенным, возвращается NULL.

Листинг 4.50. Конструкции CASE в командах.

booktown=# SELECT isbn,
booktown-# CASE WHEN cost > 20 THEN 'over $20.00 cost'
booktown-# WHEN cost = 20 THEN '$20.00 cost1
booktown-# ELSE 'under $20.00 cost'
booktown-# END AS cost_range
booktown-# FROM stock
booktown-# LIMIT 8;
Isbn | cost_range
0385121679 | over $20.00 cost
039480001X | over $20.00 cost
044100590X | over $20.00 cost
0451198492 | over $20.00 cost
0394900014 | over $20.00 cost
0441172717 | under $20.00 cost
0451160916 | over $20.00 cost
0679803335 | $20.00 cost
(8 rows)

Подзапросы PostgreSQL расширяют возможности конструкций CASE (см. раздел "Подзапросы"). Как показано в листинге 4.51, в качестве результата условного выражения в конструкции может быть задан подзапрос.

Листинг 4.51. Конструкции CASE в подзапросах.

booktown=# SELECT isbn,
booktown-# CASE WHEN cost > 20 THEN 'N/A – (Out of price range)'
booktown-# ELSE (SELECT title FROM books b JOIN editions e
booktown(# ON (b.id = e.book_id)
booktown(# WHERE e.isbn = stock.isbn)
booktown-# END AS cost_range
booktown-# FROM stock
booktown-# ORDER BY cost_range ASC
booktown-# LIMIT 8;
isbn | cost_range
0451457994 | 2001: A Space Odyssey
0394800753 | Bartholomew and the Oobleck
0441172717 | Dune
0760720002 | Little Women
0385121679 | N/A – (Out of price range)
039480001X | N/A – (Out of price range)
044100590X | N/A – (Out of price range)
0451198492 | N/A – (Out of price range)
(8 rows)

Для всех книг, цена которых не превышает 20, запрос возвращает название книги (подзапрос к таблице books) и код ISBN (основной запрос к таблице stock).

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.