ProgrammatieBI/SQL analist

Hoe werken en wat zijn de verschillen tussen de vensterfuncties ROW_NUMBER(), RANK(), DENSE_RANK() bij het programmeren van rapporten in SQL? Wat zijn de valkuilen bij het gebruik ervan?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Vensterfuncties maken het mogelijk om berekeningen uit te voeren over een "venster" van rijen, zonder ze in afzonderlijke rijen te groeperen, wat handig is voor rapporten en analyse.

  • ROW_NUMBER() - kent een unieke, opeenvolgende nummer toe aan rijen binnen elke partitionering (splitsing) van het venster, waarbij ze op een bepaalde manier gesorteerd worden. Kan hiaten in nummering retourneren bij gelijke waarden in ORDER BY.
  • RANK() - kent dezelfde rang toe aan rijen met dezelfde waarde in ORDER BY, maar slaat de nummers van de volgende elementen over (er ontstaat een onderbreking).
  • DENSE_RANK() - kent ook dezelfde rang toe aan rijen met dezelfde waarde, maar nummers volgen elkaar direct op, zonder hiaten.

Voorbeeld:

SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS num, RANK() OVER (ORDER BY salary DESC) AS rank, DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank FROM employees;

Tabel:

namesalary
Vasja10000
Petja10000
Masha9000

Resultaat:

namesalarynumrankdense_rank
Vasja10000111
Petja10000211
Masha9000332

Valkuilen:

  • Een onjuist gekozen ORDER BY kan leiden tot een verkeerde sortering.
  • (row_number) Als er geen uniek veld in ORDER BY wordt gekozen, is er geen garantie voor een stabiele volgorde.
  • Gebruik zonder PARTITION BY wanneer splitsing nodig is, leidt tot onjuiste nummering over de gehele rijset.

Vraag met een valstrik

Als er geen PARTITION BY in het venster van de functie is opgegeven, hoe zal de nummering van rijen in ROW_NUMBER() plaatsvinden?

Antwoord: De gehele gegevensset wordt als één partitionering beschouwd. Dat wil zeggen, de nummering zal doorlopend zijn over alle rijen, zonder rekening te houden met enige groeperingen.

Voorbeeld:

SELECT *, ROW_NUMBER() OVER (ORDER BY salary DESC) FROM employees; -- Alle medewerkers krijgen een uniek nummer, beginnend bij 1 zonder splitsing per afdeling

Verhaal №1

In het BI-rapport werd vergeten om PARTITION BY per afdeling op te geven. Alle medewerkers van het bedrijf kregen een opeenvolgende nummering, terwijl de taak was om de besten binnen elke afdeling te identificeren. Dit leidde tot een onjuiste TOP-N van medewerkers per afdeling.


Verhaal №2

Een ontwikkelaar koos RANK() in plaats van ROW_NUMBER() om de "beste" uit de groep te bepalen - maar bij gelijke prestaties kregen ze dezelfde nummers, waardoor impliciete duplicaten van leiders in de analyse ontstonden.


Verhaal №3

Bij het gebruik van DENSE_RANK() werd niet in aanmerking genomen dat het hiaten in rangen verbiedt, wat het rapport over het aantal "unieke" significante posities bij de verkoopanalyse vervormde. Controle op de bedrijfslogica onthulde een fout in de verdeling van plaatsen.