CodeGym /Kursy /SQL SELF /Porównanie funkcji okienkowych z agregującymi: GRO...

Porównanie funkcji okienkowych z agregującymi: GROUP BY vs PARTITION BY

SQL SELF
Poziom 30 , Lekcja 0
Dostępny

Na pierwszy rzut oka funkcje okienkowe i agregujące wydają się podobnymi narzędziami do analizy i przetwarzania danych. Przecież oba typy wykonują obliczenia, takie jak suma, średnia, ranking itd. Ale rozkminimy, czym się różnią w praktyce.

Funkcje agregujące (GROUP BY)

Funkcje agregujące działają tak:

  • Grupują wiersze według wskazanych kolumn.
  • Po grupowaniu każda grupa zamienia się w jeden wiersz wyniku.
  • Przykład: chcesz poznać łączny dochód dla każdego regionu.
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

Cechy szczególne: GROUP BY "ściska" dane. Jeśli używasz grupowania, wszystkie wiersze należące do jednej grupy znikają — zostaje tylko wynik agregacji.

Funkcje okienkowe (PARTITION BY)

Funkcje okienkowe natomiast:

  • Zachowują oryginalną strukturę danych (żadnego ściskania ani znikania wierszy!).
  • Mogą wykonywać obliczenia wewnątrz "okien" — logicznie wydzielonych grup wierszy.

Przykład: chcesz poznać udział sprzedaży każdego miasta w sumie sprzedaży jego regionu, ale zachować wszystkie dane.

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

Cechy szczególne: użycie funkcji okienkowych nie usuwa wierszy, tylko dodaje nowe wyliczone wartości do każdego wiersza.

Przykład: SUM() z GROUP BY vs SUM() z PARTITION BY

Żeby lepiej ogarnąć różnicę, zobaczmy jak SUM() działa w obu przypadkach. Załóżmy, że mamy tabelę sales_data w takim układzie:

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

Sumowanie przez GROUP BY

Chcemy poznać łączną sprzedaż dla każdego regionu:

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

Wynik będzie wyglądał tak:

region total_sales
North 250
South 450

Co się stało: wiersze zostały zgrupowane po region, a każda grupa została "ściśnięta" do jednego wiersza z sumą sprzedaży.

Sumowanie przez PARTITION BY

Teraz zróbmy to samo funkcją okienkową:

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

Wynik:

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

Co się stało: PARTITION BY nie "ściśnął" wierszy. Zamiast tego policzył sumę wewnątrz określonych okien (każdy region to osobne okno).

Kiedy używać GROUP BY, a kiedy PARTITION BY?

GROUP BY: idealny do końcowych raportów

GROUP BY przydaje się, gdy chcesz zmniejszyć ilość danych i dostać końcowe wyniki na poziomie grup. Na przykład:

  • Łączna sprzedaż według miesięcy.
  • Liczba zamówień według kategorii produktów.

Przykład:

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

PARTITION BY: super do analizy i szczegółów

PARTITION BY jest spoko, gdy musisz zachować wszystkie wiersze danych i dodatkowo coś policzyć dla każdego z nich. Na przykład:

  • Wyznaczyć udział sprzedaży każdego produktu w kategorii.
  • Numerowanie wierszy w każdej grupie.

Przykład liczenia udziału sprzedaży:

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

Przykład: użycie kilku funkcji okienkowych

Jedną z zalet funkcji okienkowych jest możliwość użycia kilku obliczeń naraz. Na przykład:

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;

Wynik:

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

Zalety funkcji okienkowych nad GROUP BY

Zachowanie oryginalnych danych: GROUP BY "ściska" wiersze, a funkcje okienkowe pozwalają zachować oryginalną strukturę tabeli.

Wiele obliczeń w jednym zapytaniu: Możesz użyć kilku funkcji okienkowych z różnymi parametrami PARTITION BY i ORDER BY, zachowując dane.

Elastyczność analizy: Funkcje okienkowe pozwalają dostosować obliczenia do twoich potrzeb: sumy narastające, ranking, obliczenia udziałów i wiele więcej.

Przykład elastyczności

Spróbujmy połączyć kilka funkcji:

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;

Wynik:

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

Ograniczenia i typowe błędy

Jednym z częstych błędów jest próba użycia PARTITION BY, gdy trzeba "ściśnąć" dane. Na przykład, zamiast:

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

Niektórzy próbują napisać tak:

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

Ale to zwróci wszystkie wiersze, nie zmniejszając ilości danych (co nie zawsze jest tym, czego chcesz).

Teraz już na pewno wiesz, kiedy używać GROUP BY, a kiedy funkcji okienkowych. To trochę jak wybór między młotkiem a śrubokrętem: oba narzędzia działają z gwoździami... ale na swój sposób.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION