Агрегация, GROUP BY и HAVING: вопросы для собеседования (часть 7)

GROUP BY, HAVING, COUNT, SUM, AVG — агрегатные функции встречаются практически в каждой SQL-задаче на собеседовании. Интервьюеры проверяют, понимаете ли вы разницу между WHERE и HAVING, умеете ли группировать по нескольким полям и фильтровать по результатам агрегации. Без уверенного владения этим блоком невозможно решить ни одну аналитическую задачу на SQL.

Даты и времяEXPLAIN и оптимизацияВыражения и NULLJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции

Вопросы 3132 из 32

31Запрос использует `GROUP BY ROLLUP(region)`. В исходных данных есть строки с `region = NULL`. Как отличить суперагрегатную строку (итог по всем) от строки с реальным `NULL`-регионом?
AПо столбцу `GROUPING(region)`: значение 1 означает реальный `NULL` в данных, 0 — суперагрегат
BС помощью `COALESCE(region, 'Итого')` — он заменяет и реальные `NULL`, и суперагрегатные строки на одинаковое значение
CС помощью `GROUPING(region)`: значение 1 означает суперагрегатную строку, 0 — реальные данные включая строки с `NULL`-регионом
DРеальные `NULL` и суперагрегаты неотличимы без изменения исходных данных
Ответ: `GROUPING(col)` возвращает 1 только для синтетических `NULL`, добавленных `ROLLUP`, и 0 для всех реальных данных, включая строки с реальным `NULL`.

`GROUPING(expr)` — функция SQL:2003, которая возвращает 1, если `NULL` в данной строке является суперагрегатным маркером, и 0 для реальных значений (включая реальные `NULL`). `COALESCE(region, 'Итого')` не различает: он заменит и реальный `NULL`, и суперагрегат на одну строку. Правильный паттерн: `CASE WHEN GROUPING(region)=1 THEN 'Итог' ELSE COALESCE(region,'Нет региона') END`.

Подробный разбор →
32Таблица `sales` содержит 2 уникальных значения в `region` и 2 уникальных значения в `channel`. Сколько максимум строк вернёт `SELECT region, channel, SUM(revenue) FROM sales GROUP BY CUBE(region, channel)`?
A4 строки: `CUBE` работает как синоним `ROLLUP` и создаёт только иерархические подытоги без полного перебора
B5 строк: `CUBE` создаёт подытоги по первому полю и общий итог, без отдельной разбивки по второму полю набора
C9 строк: `CUBE` генерирует строки для всех подмножеств полей, включая каждую пару, каждое поле и общий итог
D3 строки: `CUBE` группирует только по отдельным полям без их совместной комбинации и без строки общего итога
Ответ: `CUBE(a, b)` генерирует все 4 подмножества: `(a,b)`, `(a)`, `(b)`, `()`. При 2 значениях в каждом поле получается 4+2+2+1=9 строк.

`CUBE(a, b)` создаёт группировки для всех `2^n` подмножеств полей: `(a, b)`, `(a)`, `(b)`, `()`. При двух регионах и двух каналах: 4 пары + 2 строки по региону + 2 строки по каналу + 1 общий итог = 9. `ROLLUP(a, b)` генерирует только `(a, b)`, `(a)`, `()` — это 4+2+1=7 строк, без отдельной разбивки по `(b)`. `CUBE` перебирает все возможные комбинации, `ROLLUP` идёт иерархически справа налево.

Подробный разбор →
1234567

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать SQL в Telegram

Другие темы: SQL

Даты и времяEXPLAIN и оптимизацияВыражения и NULLJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции