Глиф Учебники

Условие в запросе — CASE WHEN

Справочник · SQL · 1 минута чтения

SQL
SELECT name, qty,
       CASE
           WHEN qty = 0 THEN 'нет в наличии'
           WHEN qty < 10 THEN 'мало'
           ELSE 'есть'
       END AS stock
FROM products
ORDER BY qty;
nameqtystock
Глобус0нет в наличии
Сумка для ноутбука5мало
Наушники8мало
Рюкзак12есть
Калькулятор25есть
Пенал40есть
Ручка150есть
Тетрадь300есть

CASE проверяет условия WHEN сверху вниз и берёт значение после THEN у первого верного. Если не подошло ни одно — значение после ELSE. Заканчивается CASE словом END, а AS даёт столбцу имя. Запись одинакова в SQLite, MySQL, PostgreSQL и SQL Server. Таблица products — из учебной базы курса, урок Добавление строк.

Порядок условий важен: если поставить WHEN qty < 10 первым, глобус с нулём попадёт в «мало».

Короткая форма

Когда сравнивается один столбец с разными значениями:

SQL
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 считает строки по разным условиям одним запросом:

SQL
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;
expensivecheap
35

С GROUP BY так строят сводные таблицы: строки — категории, столбцы — условия.

В сортировке и в UPDATE

Товары, которых нет в наличии, — в конец списка, остальные по цене:

SQL
SELECT name, price
FROM products
ORDER BY CASE WHEN qty = 0 THEN 1 ELSE 0 END, price;

Разная скидка для разных строк одной командой (на учебной базе — внутри BEGIN … ROLLBACK, как в уроке об UPDATE):

SQL
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 ServerIIF(qty > 0, 'да', 'нет')
MySQL, MariaDBIF(qty > 0, 'да', 'нет')
PostgreSQLтолько CASE

CASE работает везде, поэтому в запросах, которые могут переехать на другую СУБД, лучше он.