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.
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:
| name | salary |
|---|---|
| Vasja | 10000 |
| Petja | 10000 |
| Masha | 9000 |
Resultaat:
| name | salary | num | rank | dense_rank |
|---|---|---|---|---|
| Vasja | 10000 | 1 | 1 | 1 |
| Petja | 10000 | 2 | 1 | 1 |
| Masha | 9000 | 3 | 3 | 2 |
Valkuilen:
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.