Конструкции 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 отчасти напоминает условные команды f-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).