📁 Блок: SQL / MySQL / Оконные функции⏱️ Время изучения: ~90 мин🎯 Сложность: Продвинутая
⚡ Кратко: ошибки
Фильтровать по псевдониму оконной функции в WHERE.
Добавлять GROUP BY рядом с оконной функцией без нужды.
Забывать ORDER BY, когда нужна кумулятивная сумма.
Путать COUNT(*) и COUNT(column).
1
Ошибка: фильтрация по результату оконной функции в WHERE
Оконные функции вычисляются после WHERE, поэтому их псевдоним нельзя использовать в фильтре.
-- Неправильно
SELECT
order_id,
customer_id,
SUM(order_amount) OVER (PARTITION BY customer_id) AS total
FROM orders
WHERE total > 1000;
Как исправить: оберните запрос в подзапрос или используйте QUALIFY (где поддерживается).
-- Правильно
SELECT *
FROM (
SELECT
order_id,
customer_id,
SUM(order_amount) OVER (PARTITION BY customer_id) AS total
FROM orders
) sub
WHERE total > 1000;
2
Ошибка: лишний GROUP BY рядом с оконной функцией
GROUP BY сворачивает строки, поэтому совместное использование с оконной функцией часто приводит к ошибке или потере данных.
-- Неправильно
SELECT
product_name,
category,
COUNT(*) OVER (PARTITION BY category)
FROM products
GROUP BY category;
Как исправить: уберите GROUP BY, если нужно сохранить детальные строки.
-- Правильно
SELECT
product_name,
category,
COUNT(*) OVER (PARTITION BY category) AS products_in_category
FROM products;
3
Ошибка: отсутствие ORDER BY при кумулятивном расчёте
Без ORDER BY функция вернёт одну общую сумму, а не накопительную.
-- Неправильно: одинаковое значение во всех строках
SELECT
sale_id,
sale_date,
SUM(sale_amount) OVER () AS wrong_cumulative
FROM sales;
Как исправить: добавьте ORDER BY в окно.
-- Правильно
SELECT
sale_id,
sale_date,
SUM(sale_amount) OVER (ORDER BY sale_date) AS cumulative_sales
FROM sales;
4
Ошибка: COUNT(column) вместо COUNT(*)
COUNT(category) не посчитает строки с NULL в категории, а COUNT(*) посчитает все строки окна.
-- Может дать меньшее значение, если category содержит NULL
SELECT
product_name,
category,
COUNT(category) OVER (PARTITION BY category) AS cnt
FROM products;
-- Правильно, если нужно число всех строк группы
SELECT
product_name,
category,
COUNT(*) OVER (PARTITION BY category) AS cnt
FROM products;