- •Простой оператор select
- •Предикаты
- •Предикаты сравнения
- •Предикат in
- •Объединение
- •Пересечение и разность
- •Предикат exists
- •Получение итоговых значений
- •Предложение group by
- •Предложение having
- •Использование в запросе нескольких источников записей
- •Использование ключевых слов some (any) и all с предикатами сравнения
- •Переименование столбцов и вычисления в результирующем наборе
- •Преобразование типов и оператор cast
- •Оператор case
- •Предикат like
- •Предикат like и регулярные выражения
- •Использование значения null в условиях поиска
- •Функция datepart
- •Нумерация строк в соответствии с порядком, заданном значениями первичного ключа
- •Функция row_number
- •Декартово произведение
- •Коррелирующие подзапросы
Оператор case
Пример1: Пусть требуется вывести список всех моделей ПК с указанием их цены. При этом если модель отсутствует в продаже (ее нет в таблице РС), то вместо цены вывести текст «Нет в наличии».
Список всех моделей ПК с ценами можно получить с помощью запроса:
SELECT DISTINCT Product.model, price
FROM Product LEFT JOIN
PC ON Product.model = PC.model
WHERE product.type = 'pc'
В результирующем наборе отсутствующая цена будет заменена NULL-значением.
Чтобы заменить NULL-значения нужным текстом, можно воспользоваться оператором CASE:
SELECT DISTINCT product.model,
CASE
WHEN price IS NULL
THEN 'Нет в наличии'
ELSE CAST(price AS CHAR(20))
END price
FROM Product LEFT JOIN
PC ON Product.model = PC.model
WHERE product.type = 'pc'
Оператор CASE в зависимости от указанных условий возвращает одно из множества возможных значений. В нашем примере условием является проверка на NULL. Если это условие выполняется, то возвращается текст «Нет в наличии», в противном случае (ELSE) возвращается значение цены.
Здесь есть один принципиальный момент. Поскольку результатом оператора SELECT всегда является таблица, то все значения любого столбца должны иметь один и тот же тип данных (с учетом неявного приведения типов). Поэтому мы не можем наряду с ценой (числовой тип) выводить символьную константу. Вот почему к полю price применяется преобразование типов, чтобы привести его значения к символьному представлению.
Оператор CASE может быть использован в одной из двух синтаксических форм записи:
1-я форма:
CASE <проверяемое выражение>
WHEN <сравниваемое выражение 1>
THEN <возвращаемое значение 1>
…
WHEN <сравниваемое выражение N>
THEN <возвращаемое значение N>
[ELSE <возвращаемое значение>]
END
2-я форма:
CASE
WHEN <предикат 1>
THEN <возвращаемое значение 1>
…
WHEN <предикат N>
THEN <возвращаемое значение N>
[ELSE <возвращаемое значение>]
END
Все предложения WHEN должны иметь одинаковую синтаксическую форму, то есть нельзя смешивать первую и вторую формы. При использовании первой синтаксической формы условие WHEN удовлетворяется, как только значение проверяемого выражения станет равным значению выражения, указанного в предложении WHEN. При использовании второй синтаксической формы условие WHEN удовлетворяется, как только предикат принимает значение TRUE. При удовлетворении условия оператор CASE возвращает значение, указанное в соответствующем предложении THEN. Если ни одно из условий WHEN не выполнилось, то будет использовано значение, указанное в предложении ELSE. При отсутствии ELSE, будет возвращено NULL-значение. Если удовлетворены несколько условий, то будет возвращено значение предложения THEN первого из них, так как остальные просто не будут проверяться.
В приведенном выше примере была применена вторая форма оператора CASE.
Заметим, что для проверки на NULL стандарт предлагает более короткую форму — оператор COALESCE. Он имеет произвольное число параметров и возвращает значение первого из них, отличного от NULL. Для двух параметров оператор COALESCE(A, B) эквивалентен следующему оператору CASE:
CASE
WHEN A IS NOT NULL
THEN A
ELSE B
END
Решение рассмотренного выше примера при использовании оператора COALESCE можно переписать следующим образом:
SELECT DISTINCT Product.model,
COALESCE(CAST(price AS CHAR(20)),'Нет в наличии') price
FROM Product LEFT JOIN
PC ON Product.model = PC.model
WHERE Product.type = 'pc';
Применение первой синтаксической формы оператора CASE можно продемонстрировать на следующем примере.
Пример2: Вывести все имеющиеся модели ПК с указанием цены. Отметить самые дорогие и самые дешевые модели.
SELECT DISTINCT model, price,
CASE price
WHEN (SELECT MAX(price)
FROM PC )
THEN 'Самый дорогой'
WHEN (SELECT MIN(price)
FROM PC )
THEN 'Самый дешевый'
ELSE 'Средняя цена'
END comment
FROM PC
ORDER BY price;
В результате запроса получим:
1232 |
350.0 |
Самый дешевый |
1260 |
350.0 |
Самый дешевый |
1232 |
400.0 |
Средняя цена |
1232 |
600.0 |
Средняя цена |
1233 |
600.0 |
Средняя цена |
1121 |
850.0 |
Средняя цена |
1233 |
950.0 |
Средняя цена |
1233 |
980.0 |
Самый дорогой |