PARTITION BY w SQL - Jak analizować dane bez zwijania wierszy?

Michał Borowski 15 lutego 2026
Tabela z danymi, gdzie wiersze i kolumny to kody, a komórki zawierają 'N', 'C' lub 'I'. Możliwe zastosowanie w partition by SQL.

Spis treści

PARTITION BY w SQL to jedna z tych technik, które od razu porządkują pracę z danymi, gdy zwykłe agregacje przestają wystarczać. Pozwala liczyć rankingi, sumy, średnie i zestawienia osobno dla każdej grupy, ale bez utraty szczegółów na poziomie pojedynczego wiersza. W praktyce to narzędzie, które bardzo często rozwiązuje problemy z analizą wyników sprzedaży, listą pracowników, statystykami użytkowników czy raportami per kategoria.

Najkrótsza droga do zrozumienia partycji w SQL

  • PARTITION BY dzieli dane na logiczne grupy wewnątrz funkcji okienowej, a nie w całym wyniku zapytania.
  • Najczęściej używa się go z OVER oraz opcjonalnym ORDER BY.
  • To nie to samo co GROUP BY: tutaj dalej widzisz każdy wiersz osobno.
  • Świetnie sprawdza się przy ROW_NUMBER(), RANK(), sumach kroczących i top N per grupa.
  • Najczęstszy błąd to próba filtrowania wyniku funkcji okiennej bezpośrednio w WHERE.
  • Jeśli chcesz wynik całej partycji, często trzeba świadomie kontrolować ORDER BY albo ramkę okna.

Co robi PARTITION BY i kiedy naprawdę się przydaje

Najprościej mówiąc, PARTITION BY wyznacza podzbiory wierszy, na których ma pracować funkcja okienna. Jeśli masz tabelę z pracownikami, możesz osobno policzyć ranking w każdym dziale, a jeśli analizujesz sprzedaż, możesz liczyć sumy osobno dla każdego miesiąca, regionu albo produktu. Dane nadal pozostają wiersz po wierszu, ale wynik funkcji zmienia się w zależności od grupy, do której należy rekord.

To właśnie odróżnia tę technikę od klasycznego grupowania. Nie dostajesz jednego wiersza na grupę, tylko cały zestaw wierszy z dopisanym obliczeniem. Z mojego doświadczenia wynika, że to największa przewaga PARTITION BY: raport staje się jednocześnie szczegółowy i analityczny.

W praktyce sens tej konstrukcji pojawia się wtedy, gdy chcesz odpowiedzieć na pytania typu: kto jest pierwszy w swoim dziale, ile sprzedano w danej kategorii, jaka jest średnia per segment albo jak wygląda kolejność zdarzeń dla jednego użytkownika. Następny krok to zrozumienie, dlaczego samo PARTITION BY nie wystarczy bez całej składni okna.

Jak działa to połączenie z OVER i ORDER BY

PARTITION BY nie działa samodzielnie. Zawsze jest częścią definicji okna, czyli fragmentu zapytania w stylu OVER (PARTITION BY ... ORDER BY ...). OVER mówi silnikowi, że funkcja ma działać „na oknie”, a PARTITION BY ustawia granice tego okna. Jeśli dodasz ORDER BY, określasz też kolejność w obrębie każdej partycji.

To ma duże znaczenie. Bez ORDER BY wiele funkcji daje wynik zbiorczy dla całej partycji. Z ORDER BY możesz uzyskać na przykład ranking albo sumę kroczącą. Właśnie dlatego ta sama funkcja może zachowywać się zupełnie inaczej w dwóch pozornie podobnych zapytaniach.

SELECT
  employee_name,
  department,
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS rn,
  SUM(salary) OVER (
    PARTITION BY department
  ) AS department_total
FROM employees;

W pierwszym wyliczeniu numerujesz pracowników w obrębie działu według pensji. W drugim dostajesz tę samą sumę przypisaną do każdego wiersza w danym dziale. Jeśli dodasz ORDER BY do sumy, wynik może zmienić się w sumę narastającą, a nie pełną sumę całej partycji. To jest detal, który początkujący często przeoczają, a potem dziwią się, że wynik „nie zgadza się z intuicją”.

Właśnie dlatego warto najpierw dobrze opanować relację między partycją, sortowaniem i ramką okna, a dopiero potem przechodzić do porównań z GROUP BY.

Schemat przedstawia bazę danych podzieloną na partycje (Partition 1, 2, 3), a każda partycja zawiera dane (Data 1-6).

PARTITION BY a GROUP BY w praktyce

To porównanie jest obowiązkowe, bo te dwie konstrukcje bywają mylone nawet przez osoby, które już piszą raporty w SQL. GROUP BY agreguje i zwija wiersze. PARTITION BY agreguje bez zwijania. To naprawdę cały rdzeń różnicy.

Cecha GROUP BY PARTITION BY
Wynik Jeden wiersz na grupę Wiele wierszy, z dopisaną wartością okienową
Cel Agregacja całych grup Analiza wierszy wewnątrz grup
Widoczność szczegółów Tracisz szczegóły wierszy Zachowujesz każdy rekord
Typowe zastosowanie Suma sprzedaży per miesiąc Ranking sprzedaży w każdym miesiącu
Przykładowa funkcja SUM() ROW_NUMBER(), RANK(), SUM() OVER

Jeśli potrzebujesz tylko odpowiedzi „ile było zamówień w kategorii”, GROUP BY wystarczy. Jeśli chcesz jednocześnie zobaczyć każde zamówienie i jego pozycję na tle kategorii, PARTITION BY jest właściwym wyborem. Ja zwykle patrzę na to tak: GROUP BY służy do raportu zbiorczego, a PARTITION BY do raportu analitycznego.

Ta różnica najlepiej widać na przykładach, bo dopiero na nich wychodzi, dlaczego takie samo źródło danych może dać dwa zupełnie różne typy wyniku.

Najpraktyczniejsze wzorce użycia na realnych danych

Najbardziej użyteczne scenariusze są zaskakująco powtarzalne. W codziennej pracy najczęściej spotykam trzy wzorce: ranking w grupie, top N per grupa i obliczenia narastające. Każdy z nich rozwiązuje inny problem, ale wszystkie opierają się na tej samej idei: podziel dane na logiczne części i licz w obrębie każdej z nich.

Ranking w każdej grupie

SELECT
  department,
  employee_name,
  salary,
  RANK() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS salary_rank
FROM employees;

To dobry wybór, gdy chcesz pokazać nie tylko lidera, ale też kolejność pozostałych osób. RANK() przydaje się szczególnie wtedy, gdy dopuszczasz remisy, bo kilka rekordów może dostać ten sam numer.

Top 3 w każdej grupie

WITH ranked AS (
  SELECT
    department,
    employee_name,
    salary,
    ROW_NUMBER() OVER (
      PARTITION BY department
      ORDER BY salary DESC
    ) AS rn
  FROM employees
)
SELECT *
FROM ranked
WHERE rn <= 3;

To klasyczny przypadek, w którym PARTITION BY wygrywa z prostym podejściem opartym o wiele podzapytań. Ważny szczegół: filtrujesz dopiero wynik po obliczeniu funkcji okiennej, więc zwykle potrzebujesz CTE albo podzapytania. Bez tego łatwo wpaść w błąd logiczny.

Przeczytaj również: Czym jest freeware - Jak bezpiecznie używać darmowych programów?

Suma narastająca w obrębie grupy

SELECT
  order_date,
  customer_id,
  amount,
  SUM(amount) OVER (
    PARTITION BY customer_id
    ORDER BY order_date
  ) AS running_total
FROM orders;

Taki wzorzec świetnie pokazuje, jak zmienia się wartość w czasie dla jednego klienta, jednego konta albo jednej kampanii. To jest już analiza dynamiczna, a nie zwykła agregacja statyczna. Właśnie tutaj dobrze widać, dlaczego kolejność danych ma tak duże znaczenie.

Jeśli te przykłady są czytelne, łatwiej będzie też rozpoznać miejsca, w których zapytanie zaczyna działać nie tak, jak autor miał na myśli.

Typowe błędy i ograniczenia, które psują wynik

Najczęstszy błąd to próba filtrowania funkcji okiennej bezpośrednio w WHERE. To nie działa, bo funkcje okienne są liczone po filtracji podstawowej, a przed końcowym sortowaniem wyniku. Innymi słowy: kolumna z rankiem jeszcze nie istnieje wtedy, gdy SQL wykonuje WHERE. Dlatego potrzebujesz CTE, podzapytania albo czasem dodatkowej warstwy logiki.

Drugi częsty problem dotyczy mylenia ORDER BY w oknie z ORDER BY całego zapytania. To nie są te same rzeczy. Pierwsze ustala kolejność liczenia wewnątrz partycji, drugie porządkuje końcowy wynik. Możesz mieć idealnie policzony ranking, a mimo to pokazać wiersze w zupełnie innej kolejności.

Trzeci kłopot pojawia się przy funkcjach agregujących z ORDER BY. Jeśli do sumy dodasz sortowanie, bardzo często dostaniesz wynik narastający, a nie pełną sumę całej grupy. To nie jest błąd silnika, tylko efekt domyślnej ramki okna. Gdy chcesz sumę dla całej partycji, zwykle lepiej nie dokładać ORDER BY albo jawnie ustawić zakres okna.

  • Nie zakładaj, że PARTITION BY zawsze zwraca jedną wartość na grupę.
  • Nie filtruj rankingu w tej samej warstwie, w której go liczysz.
  • Nie myl kolejności w oknie z kolejnością końcowego wyniku.
  • Nie zapominaj, że różne silniki SQL mają drobne różnice w obsłudze ramek i szczegółów składni.

Te ograniczenia nie przekreślają techniki. One tylko pokazują, że PARTITION BY wymaga precyzji, a nie mechanicznego kopiowania wzorca z innego zapytania.

Jak pisać takie zapytania, żeby były czytelne i szybkie

Jeśli buduję zapytanie z funkcją okienową, najpierw dbam o czytelność, a dopiero potem o kosmetykę. Dobrze nazwane aliasy, osobne CTE dla rankingu i logiczny podział kroków robią większą różnicę niż próba upchnięcia wszystkiego w jednym SELECT. To szczególnie ważne, gdy zapytanie ma wrócić za trzy miesiące do poprawki.

Wydajnościowo warto pamiętać o jednej rzeczy: PARTITION BY nie jest darmowe. Silnik musi przeanalizować dane w obrębie partycji, a przy ORDER BY często dochodzi też sortowanie. Na dużych tabelach pomaga sensowny indeks na kolumnach używanych do partycjonowania i sortowania, ale nie jest to uniwersalna gwarancja. Zależy od silnika, rozmiaru danych i tego, jak selektywne są filtry wejściowe.

Ja zwykle stosuję kilka prostych zasad:

  • używam CTE lub podzapytania, gdy wynik funkcji okiennej ma być dalej filtrowany,
  • nazywam kolumny pomocnicze tak, by było jasne, czy to ranking, suma narastająca czy licznik,
  • nie dodaję ORDER BY w oknie bez powodu,
  • testuję wynik na małej próbce danych, zanim odpalę zapytanie na pełnej tabeli,
  • sprawdzam, czy problem da się rozwiązać GROUP BY, bo czasem jest to prostsze i tańsze obliczeniowo.

To podejście dobrze zamyka temat: chodzi nie tylko o samą składnię, ale o świadome użycie narzędzia tam, gdzie rzeczywiście daje przewagę.

Co warto zapamiętać, zanim wkleisz to do własnego raportu

Jeśli miałbym zostawić jedną praktyczną myśl, powiedziałbym tak: PARTITION BY porządkuje analizę w obrębie grup, ale nie zastępuje zwykłej agregacji. To technika do rankingów, sum kroczących, porównań wewnątrz segmentów i wszędzie tam, gdzie chcesz zachować pełen kontekst pojedynczego wiersza.

Najlepsze rezultaty daje wtedy, gdy jasno rozumiesz trzy rzeczy naraz: po czym dzielisz dane, po czym je sortujesz i czy potrzebujesz pełnej wartości grupy, czy tylko wyniku narastającego. Gdy te elementy są ustawione poprawnie, SQL przestaje być zbiorem sztuczek, a zaczyna działać jak precyzyjne narzędzie analityczne.

Jeżeli chcesz dalej rozwijać ten temat, następny krok jest bardzo konkretny: weź własną tabelę, wybierz jedną grupę, dodaj ranking albo sumę narastającą i porównaj wynik z wersją opartą wyłącznie na GROUP BY. W praktyce właśnie taki eksperyment najszybciej pokazuje, gdzie PARTITION BY naprawdę oszczędza czas i upraszcza logikę zapytania.

FAQ - Najczęstsze pytania

Główną różnicą jest to, że GROUP BY zwija wiersze do jednego rekordu na grupę, tracąc szczegóły. PARTITION BY pozwala wykonywać obliczenia agregujące, zachowując jednocześnie każdy wiersz i jego indywidualne dane w wyniku zapytania.

Nie, PARTITION BY nie występuje samodzielnie. Jest ono integralną częścią definicji okna i musi znajdować się wewnątrz klauzuli OVER, która informuje silnik SQL, że funkcja ma zostać wykonana na określonym zbiorze wierszy.

SQL wykonuje filtrowanie WHERE przed obliczeniem funkcji okienkowych. Aby odfiltrować np. Top 3 wyniki rankingu, musisz umieścić zapytanie z PARTITION BY wewnątrz CTE lub podzapytania, a filtrację wykonać w warstwie zewnętrznej.

Najczęściej używa się go z funkcjami rankingowymi (ROW_NUMBER, RANK, DENSE_RANK) oraz funkcjami agregującymi (SUM, AVG, COUNT, MIN, MAX). Pozwala to na tworzenie zestawień wewnątrz kategorii przy zachowaniu pełnego kontekstu danych.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

partition by sql
partition by sql przykłady
sql partition by a group by różnice
jak działa partition by w sql
Autor Michał Borowski
Michał Borowski
Jestem Michał Borowski, doświadczonym twórcą treści oraz analitykiem w dziedzinie nowoczesnych technologii, programowania i sztucznej inteligencji. Od ponad pięciu lat zajmuję się analizowaniem trendów rynkowych oraz pisaniem o innowacjach technologicznych, co pozwoliło mi zdobyć głęboką wiedzę na temat dynamicznie zmieniającego się świata IT. Moim celem jest uproszczenie skomplikowanych zagadnień technologicznych, aby były one zrozumiałe dla każdego, niezależnie od poziomu zaawansowania. W swojej pracy kładę duży nacisk na rzetelność i obiektywizm, starając się dostarczać aktualne i wiarygodne informacje, które mogą pomóc moim czytelnikom w podejmowaniu świadomych decyzji. Dzięki moim badaniom i pasji do technologii, mam nadzieję inspirować innych do odkrywania i eksplorowania możliwości, jakie niesie ze sobą współczesny świat technologii.

Udostępnij artykuł

Napisz komentarz