Условие в запросе — CASE WHEN
SELECT name, qty,
CASE
WHEN qty = 0 THEN 'нет в наличии'
WHEN qty < 10 THEN 'мало'
ELSE 'есть'
END AS stock
FROM products
ORDER BY qty;| name | qty | stock |
|---|---|---|
| Глобус | 0 | нет в наличии |
| Сумка для ноутбука | 5 | мало |
| Наушники | 8 | мало |
| Рюкзак | 12 | есть |
| Калькулятор | 25 | есть |
| Пенал | 40 | есть |
| Ручка | 150 | есть |
| Тетрадь | 300 | есть |
CASE проверяет условия WHEN сверху вниз и берёт значение после THEN у первого верного. Если не подошло ни одно — значение после ELSE. Заканчивается CASE словом END, а AS даёт столбцу имя. Запись одинакова в SQLite, MySQL, PostgreSQL и SQL Server. Таблица products — из учебной базы курса, урок Добавление строк.
Порядок условий важен: если поставить WHEN qty < 10 первым, глобус с нулём попадёт в «мало».
Короткая форма
Когда сравнивается один столбец с разными значениями:
SELECT name,
CASE category
WHEN 'Техника' THEN 'электроника'
WHEN 'Сумки' THEN 'аксессуары'
ELSE 'прочее'
END AS grp
FROM products;Без ELSE неподошедшие строки получат NULL. С NULL короткая форма не работает: CASE category WHEN NULL … никогда не сработает — пишите CASE WHEN category IS NULL THEN ….
Подсчёт по условиям
CASE внутри SUM считает строки по разным условиям одним запросом:
SELECT SUM(CASE WHEN price >= 50 THEN 1 ELSE 0 END) AS expensive,
SUM(CASE WHEN price < 50 THEN 1 ELSE 0 END) AS cheap
FROM products;| expensive | cheap |
|---|---|
| 3 | 5 |
С GROUP BY так строят сводные таблицы: строки — категории, столбцы — условия.
В сортировке и в UPDATE
Товары, которых нет в наличии, — в конец списка, остальные по цене:
SELECT name, price
FROM products
ORDER BY CASE WHEN qty = 0 THEN 1 ELSE 0 END, price;Разная скидка для разных строк одной командой (на учебной базе — внутри BEGIN … ROLLBACK, как в уроке об UPDATE):
UPDATE products
SET price = CASE
WHEN price > 50 THEN price - 5
ELSE price - 1
END
WHERE category = 'Сумки';Без WHERE UPDATE изменит все строки таблицы, а без ELSE в CASE строки, не подошедшие ни под одно условие, получат NULL (или ошибку, если столбец NOT NULL). Проверьте выражение сначала в SELECT.
Короткие функции
| СУБД | Запись |
|---|---|
| SQLite 3.32 и новее, SQL Server | IIF(qty > 0, 'да', 'нет') |
| MySQL, MariaDB | IF(qty > 0, 'да', 'нет') |
| PostgreSQL | только CASE |
CASE работает везде, поэтому в запросах, которые могут переехать на другую СУБД, лучше он.