Как сделать SQL запрос для подсчета количества сотрудников в категориях зарплаты с выводом 0 для пустых категорий
Что проверяют
Понимаете ли вы, что пустая категория не может появиться из таблицы сотрудников: строки для неё берутся из справочника категорий. Следом обычно просят добавить фильтр, например по отделу, и смотрят, не превратится ли LEFT JOIN во внутреннее соединение.
Как отвечать
Базовая схема: ведущая таблица это список категорий, к ней LEFT JOIN сотрудников и COUNT по колонке правой таблицы. Если справочника нет, категории задаются прямо в запросе:
WITH buckets(name, lo, hi, ord) AS (
VALUES ('до 100 тыс.', 0, 100000, 1),
('100-200 тыс.', 100000, 200000, 2),
('от 200 тыс.', 200000, NULL, 3)
)
SELECT b.name, COUNT(e.id) AS cnt
FROM buckets b
LEFT JOIN employees e
ON e.salary >= b.lo
AND (b.hi IS NULL OR e.salary < b.hi)
AND e.department_id = 5
GROUP BY b.name, b.ord
ORDER BY b.ord;Что здесь важно проговорить:
COUNT(e.id), а неCOUNT(*): у пустой категории послеLEFT JOINостаётся одна строка сNULL, иCOUNT(*)покажет 1;- полуоткрытые интервалы
>= lo AND < hi: зарплата ровно 100 000 попадает в одну категорию, а не в две; - фильтр по сотрудникам в
ON: условие вWHEREотбросит строки сNULL, и пустые категории исчезнут; - порядок через
ord: сортировка по названию выстроит категории по алфавиту, а не по возрастанию.
Если сотрудников сначала агрегируют в подзапросе и потом присоединяют, пустым категориям нужен COALESCE(cnt, 0). Отдельно стоит спросить, что делать с NULL в зарплате: такие люди не попадут ни в одну категорию.
Где спотыкаются
Раскладывают сотрудников по категориям через CASE и GROUP BY по таблице сотрудников. Категория без людей просто не появится в результате.
Пишут COUNT(*) и получают единицы вместо нулей.
Используют BETWEEN для соседних диапазонов. Граничное значение считается дважды, и сумма по категориям больше числа сотрудников.