Jak działa DENSE_RANK w języku SQL? Przykłady zastosowania

Jak działa DENSE_RANK w języku SQL? Przykłady zastosowania

Pracując z bazami danych, często potrzebujemy nadać wynikiem zapytań określoną kolejność i rangę. W SQL mamy do dyspozycji różne funkcje rankingowe, a jedną z nich jest DENSE_RANK(). Czym ona się wyróżnia i jak ją właściwie stosować? W tym artykule przyjrzę się dokładnie działaniu DENSE_RANK, omówię jej zastosowania i przedstawię konkretne przykłady.

Co to jest DENSE_RANK?

DENSE_RANK() to funkcja okna (window function) w SQL, która służy do nadawania rang rekordom w obrębie określonego podziału (PARTITION BY), bazując na określonej kolejności (ORDER BY). W przeciwieństwie do klasycznej numeracji wierszy, zachowuje ona kolejność bez pominięć. Oznacza to, że jeśli dwa rekordy mają identyczną wartość sortowania, otrzymują tę samą rangę, a następny wiersz dostaje kolejność o jeden wyższą bez pominięcia wartości.

Jak działa DENSE_RANK w języku SQL?

Przyjrzyjmy się prostej tabeli zawierającej informacje o sprzedaży:

CREATE TABLE Sprzedaz (
    ID INT PRIMARY KEY,
    Sprzedawca VARCHAR(50),
    WartoscSprzedazy DECIMAL(10,2)
);

INSERT INTO Sprzedaz (ID, Sprzedawca, WartoscSprzedazy) VALUES
(1, 'Anna', 500.00),
(2, 'Marek', 800.00),
(3, 'Karol', 800.00),
(4, 'Ewa', 600.00),
(5, 'Tomasz', 500.00),
(6, 'Kasia', 900.00);

Teraz użyjmy DENSE_RANK(), by przypisać rangę sprzedawcom według wartości sprzedaży:

SELECT 
    Sprzedawca, 
    WartoscSprzedazy, 
    DENSE_RANK() OVER (ORDER BY WartoscSprzedazy DESC) AS Ranga
FROM Sprzedaz;

Wynik zapytania:

Sprzedawca WartoscSprzedazy Ranga
Kasia 900.00 1
Marek 800.00 2
Karol 800.00 2
Ewa 600.00 3
Anna 500.00 4
Tomasz 500.00 4

Zwróć uwagę, że liczba rang nie zawiera przerw. Mamy dwie osoby na miejscu 2, ale kolejny wiersz otrzymuje 3, a nie 4. To jest kluczowa różnica między DENSE_RANK a RANK(), który pozostawiłby lukę w numeracji.

DENSE_RANK vs. RANK vs. ROW_NUMBER

Funkcja DENSE_RANK() jest często mylona z innymi funkcjami rankingowymi w SQL, dlatego warto porównać ich działanie:

  • RANK() – przypisuje rangi identycznie jak DENSE_RANK(), ale jeśli dwie wartości się powtarzają, następna ranga zostanie pominięta.
  • DENSE_RANK() – nadaje rangi kolejnym wartościom, ale nie pomija numeracji.
  • ROW_NUMBER() – nadaje unikalny numer każdemu wierszowi, nawet jeśli wartości są identyczne.

Przykładowe zestawienie działania tych funkcji:

SELECT 
    Sprzedawca, 
    WartoscSprzedazy,
    RANK() OVER (ORDER BY WartoscSprzedazy DESC) AS Rank,
    DENSE_RANK() OVER (ORDER BY WartoscSprzedazy DESC) AS DenseRank,
    ROW_NUMBER() OVER (ORDER BY WartoscSprzedazy DESC) AS RowNumber
FROM Sprzedaz;

Załóżmy, że wynik wygląda tak:

Sprzedawca WartoscSprzedazy Rank DenseRank RowNumber
Kasia 900.00 1 1 1
Marek 800.00 2 2 2
Karol 800.00 2 2 3
Ewa 600.00 4 3 4
Anna 500.00 5 4 5
Tomasz 500.00 5 4 6

Widzimy kilka istotnych różnic:

  1. RANK() pominęło pozycję 3, ponieważ dwóch sprzedawców miało taką samą wartość.
  2. DENSE_RANK() nie pomija liczb, dzięki czemu trzecia ranga jest poprawnie użyta.
  3. ROW_NUMBER() przypisuje unikalne numery niezależnie od wartości sprzedaży.

Gdzie warto stosować DENSE_RANK?

Funkcja DENSE_RANK() jest bardzo przydatna w różnych scenariuszach:

  • Ranking sprzedawców lub produktów bez dziur w numeracji.
  • Analiza sportowych tabel wyników, gdzie wielu zawodników może mieć tę samą pozycję.
  • Tworzenie grup w raportach biznesowych z zachowaniem logicznej kolejności.

Podsumowanie

DENSE_RANK() to świetne narzędzie dla każdego, kto potrzebuje analizować dane rankingowe w SQL. Dzięki temu, że unika pominiętych wartości, nadaje się idealnie do raportowania i analiz, gdzie klasyfikacja jest istotna. Jeśli potrzebujesz funkcji rankingowej bez luk, DENSE_RANK() będzie najlepszym wyborem.

 

Inny ciekawy artykuł:

Jak działa RANK w języku SQL? Przykłady zastosowania

KajoDataSpace