Агрегация, 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`, оба создают только иерархические подытоги
B9 строк: `CUBE` генерирует строки для всех подмножеств полей, включая каждую пару, каждое поле отдельно и общий итог
C5 строк: `CUBE` создаёт подытоги только по первому полю и общий итог без второго
D3 строки: `CUBE` группирует только по отдельным полям без их совместной комбинации
Ответ: `CUBE(a, b)` генерирует все 4 подмножества: `(a,b)`, `(a)`, `(b)`, `()`. При 2 регионах и 2 каналах: 4+2+2+1=9 строк.

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

1234567

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

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

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

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

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