SQL leren: Rangschikken met RANK en DENSE_RANK
Gelijke tijd
In de heuvelrit naar Galmaarden kwamen de renners in groepjes over de meet. Wie samen aankomt, krijgt dezelfde tijd. "Dan delen ze ook hun plaats in de tijdsuitslag", zegt Griet. `ROW_NUMBER` kent geen gedeelde plaatsen. Tijd voor iets beters.
Gedeelde plaatsen
RANK() werkt als ROW_NUMBER(), maar rijen met dezelfde waarde krijgen hetzelfde nummer. Daarna slaat hij plaatsen over: na drie renners op plaats 2 komt plaats 5.
Hier de achterstand in etappe 3, in seconden. De WHERE loopt eerst, dus alleen de renners van die rit worden gerangschikt.
SELECT r.naam, u.achterstand, RANK() OVER (ORDER BY u.achterstand) AS rang FROM uitslagen u JOIN renners r ON r.id = u.renner_id WHERE u.etappe_id = 3| naam | achterstand | rang |
|---|---|---|
| Wout De Clercq | 0 | 1 |
| Tibo Lauwers | 42 | 2 |
| Jesper Kuipers | 42 | 2 |
| Louis Garnier | 42 | 2 |
| Arne Van Hecke | 94 | 5 |
| Kasper Holm | 94 | 5 |
| Ruben de Graaf | 94 | 5 |
| Jens Moreels | 162 | 8 |
Drie manieren van tellen
Naast elkaar, voor etappe 4. ROW_NUMBER geeft altijd verschillende nummers, ook bij gelijke tijd: wie dan voorgaat, kiest SQLite zelf. RANK deelt plaatsen en slaat daarna over. DENSE_RANK deelt ook, maar slaat niets over: na drie keer 2 komt 3.
SELECT renner_id, achterstand,
ROW_NUMBER() OVER (ORDER BY achterstand) AS rij,
RANK() OVER (ORDER BY achterstand) AS rang,
DENSE_RANK() OVER (ORDER BY achterstand) AS dicht
FROM uitslagen WHERE etappe_id = 4| renner_id | achterstand | rij | rang | dicht |
|---|---|---|---|---|
| 11 | 0 | 1 | 1 | 1 |
| 2 | 18 | 2 | 2 | 2 |
| 10 | 38 | 3 | 3 | 3 |
| 13 | 38 | 4 | 3 | 3 |
| 9 | 65 | 5 | 5 | 4 |
| 3 | 73 | 6 | 6 | 5 |
| 8 | 73 | 7 | 6 | 5 |
| 12 | 73 | 8 | 6 | 5 |
Rangschikken na GROUP BY
Window functions lopen na GROUP BY. Daarom mag je rangschikken op een totaal: RANK() OVER (ORDER BY SUM(...) DESC).
Hier het ploegenklassement op punten: eerst per ploeg optellen, dan rangschikken.
SELECT p.naam AS ploeg, SUM(u.punten) AS punten,
RANK() OVER (ORDER BY SUM(u.punten) DESC) AS plaats
FROM uitslagen u
JOIN renners r ON r.id = u.renner_id
JOIN ploegen p ON p.id = r.ploeg_id
GROUP BY p.id, p.naam| ploeg | punten | plaats |
|---|---|---|
| Polderwind | 94 | 1 |
| Équipe Nord | 72 | 2 |
| Flandrien Pro | 57 | 3 |
| Pajot Cycling | 41 | 4 |
Probeer het zelf
Maak het puntenklassement van de renners. Toon de naam, het totaal aantal punten en de plaats. Wie evenveel punten heeft, deelt de plaats en de volgende plaats wordt overgeslagen.
Klaar voor meer?
De volledige les heeft 5 oefeningen, van makkelijk naar uitdagend, met hints, punten en een reeks die je kan opbouwen.
Begin aan de les