Оконные функции — один из самых частых вопросов на собеседовании аналитика. ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, SUM OVER — всё это нужно знать наизусть. Интервьюеры проверяют, умеете ли вы решать задачи без подзапросов и самосоединений.
Чтобы получить «вчерашний `dau`», нужно определить порядок по времени через `ORDER BY dt`. Чтобы сравнение шло внутри одной платформы, нужен `PARTITION BY platform`. Поэтому корректно: `LAG(dau) OVER (PARTITION BY platform ORDER BY dt)`. Без `ORDER BY` понятие «предыдущий день» не определено, а без `PARTITION BY` вы будете сравнивать разные платформы между собой.
Подробный разбор →Фрагмент `amount / SUM(amount) OVER (PARTITION BY user_id)` считает общий `SUM(amount)` по каждому `user_id` и делит сумму конкретной транзакции на этот общий итог. Так сохраняются все строки транзакций, что важно для анализа вкладов/долей. Если использовать `GROUP BY user_id`, вы схлопнете данные до одной строки на пользователя и потеряете детализацию по транзакциям.
Подробный разбор →`SUM(amount) OVER (PARTITION BY user_id ORDER BY paid_at)` суммирует `amount` внутри каждого `user_id` в порядке `paid_at`, возвращая кумулятивный итог в каждой строке. Без `ORDER BY` получится общий итог по пользователю, повторенный в каждой строке. Без `PARTITION BY` накопление будет считаться по всем пользователям вместе, что ломает пользовательскую аналитику.
Подробный разбор →Окно `OVER (PARTITION BY product_id)` задает группу строк товара, но не задает их порядок. Без `ORDER BY dt` невозможно определить, какая строка «вчера», поэтому `LAG(price)` может вернуть не то значение, которое вы ожидаете во временном ряду. Чтобы анализировать динамику, используйте `LAG(price) OVER (PARTITION BY product_id ORDER BY dt)` (и при совпадениях добавьте тай-брейкер).
Подробный разбор →`DENSE_RANK()` дает одинаковый ранг равным значениям, а следующий ранг увеличивает на 1: 1, 2, 2, 3... Это подходит, когда места должны идти без пропусков. В `RANK()` после равенства появляются пропуски (1, 2, 2, 4...). `ROW_NUMBER()` вообще не выделяет одинаковые места: у каждой строки свой номер.
Подробный разбор →В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.
Тренировать SQL в Telegram