JavaRush /Курси /SQL SELF /Порівняння window-функцій з агрегатними функціями:

Порівняння window-функцій з агрегатними функціями: GROUP BY vs PARTITION BY

SQL SELF
Рівень 30 , Лекція 0
Відкрита

На перший погляд, window-функції та агрегатні функції здаються схожими інструментами для аналізу та обробки даних. Бо і ті, і інші роблять обчислення, такі як сума, середнє, ранжування і т.д. Але давай розберемося, чим вони реально відрізняються.

Агрегатні функції (GROUP BY)

Агрегатні функції працюють так:

  • Вони групують рядки по вказаних стовпцях.
  • Після групування кожна група перетворюється на один рядок результату.
  • Приклад: ти хочеш дізнатися сумарний дохід по кожному регіону.
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

Особливість: GROUP BY "стискає" дані. Якщо ти юзаєш групування, то всі рядки, що входять в одну групу, зникають — залишається тільки результат агрегації.

Window-функції (PARTITION BY)

Window-функції, навпаки:

  • Зберігають початкову структуру даних (ніяких стискань чи зникнень рядків!).
  • Можуть робити обчислення всередині "вікон" — логічно відокремлених груп рядків.

Приклад: ти хочеш дізнатися долю продажів кожного міста в сумарних продажах його регіону, але при цьому зберегти всі дані.

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;

Особливість: використання window-функцій не видаляє рядки, а просто додає нові обчислювані значення до кожного рядка.

Приклад: SUM() з GROUP BY vs SUM() з PARTITION BY

Щоб краще зрозуміти різницю, давай подивимось, як SUM() працює в обох випадках. Уявімо, що у нас є таблиця sales_data такого вигляду:

region city sales
North CityA 100
North CityB 150
South CityC 200
South CityD 250

Сумування за допомогою GROUP BY

Ми хочемо дізнатися загальний обсяг продажів по кожному регіону:

SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

Результат буде такий:

region total_sales
North 250
South 450

Що сталося: рядки згрупувалися по region, і кожна група була "стиснута" в один рядок із сумою продажів.

Сумування за допомогою PARTITION BY

Тепер зробимо те ж саме з window-функцією:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;

Результат:

region city sales total_sales_by_region
North CityA 100 250
North CityB 150 250
South CityC 200 450
South CityD 250 450

Що сталося: PARTITION BY не "стиснув" рядки. Замість цього він зробив розрахунок суми всередині певних вікон (кожен регіон — це окреме вікно).

Коли юзати GROUP BY, а коли — PARTITION BY?

GROUP BY: підходить для фінальних звітів

GROUP BY корисний, коли ти хочеш зменшити обсяг даних і отримати підсумкові результати на рівні груп. Наприклад:

  • Сумарні продажі по місяцях.
  • Підрахунок кількості замовлень по категоріях товарів.

Приклад:

SELECT category, COUNT(*) AS total_orders
FROM orders
GROUP BY category;

PARTITION BY: ідеальний для аналізу та деталізації

PARTITION BY підходить, коли треба зберегти всі рядки даних і додатково порахувати щось для кожного з них. Наприклад:

  • Визначити долю продажів кожного товару в категорії.
  • Нумерація рядків всередині кожної групи.

Приклад розрахунку долі продажів:

SELECT
    category,
    product,
    sales,
    ROUND(
        (sales * 100.0) / SUM(sales) OVER (PARTITION BY category),
        2
    ) AS sales_percentage
FROM sales_data;

Приклад: використання кількох window-функцій

Одна з переваг window-функцій — можливість юзати кілька обчислень одразу. Наприклад:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales,
    RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS sales_rank
FROM sales_data;

Результат:

region city sales total_sales sales_rank
North CityB 150 250 1
North CityA 100 250 2
South CityD 250 450 1
South CityC 200 450 2

Переваги window-функцій над GROUP BY

Збереження оригінальних даних: GROUP BY "стискає" рядки, а window-функції дозволяють зберегти оригінальну структуру таблиці.

Кілька обчислень в одному запиті: Ти можеш юзати кілька window-функцій з різними параметрами PARTITION BY і ORDER BY, зберігаючи дані.

Гнучкість аналізу: Window-функції дозволяють налаштувати розрахунки під свої задачі: накопичувальні суми, ранжування, долеві розрахунки і ще купу всього.

Приклад гнучкості

Спробуємо об'єднати кілька функцій:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales,
    AVG(sales) OVER (PARTITION BY region) AS avg_sales,
    RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS rank
FROM sales_data;

Результат:

region city sales total_sales avg_sales rank
North CityB 150 250 125.0 1
North CityA 100 250 125.0 2
South CityD 250 450 225.0 1
South CityC 200 450 225.0 2

Обмеження та типові помилки

Одна з поширених помилок — спроба юзати PARTITION BY, коли треба "стиснути" дані. Наприклад, замість:

SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

Дехто намагається написати так:

SELECT
    region,
    SUM(sales) OVER (PARTITION BY region) AS total_sales
FROM sales_data;

Але це поверне всі рядки, не скоротивши обсяг даних (що не завжди те, що треба).

Тепер ти точно знаєш, коли юзати GROUP BY, а коли — window-функції. Це як вибір між молотком і викруткою: обидва інструменти працюють з цвяхами... але по-різному.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ