SQL resultaten sorteren op specifieke rij

Het kan voorkomen dat je een SQL resultaatset wilt sorteren, maar dat je een bepaalde rij eerst als eerste (of juist als laatste) in de set wilt hebben. In dat geval zul je een aanpassing moeten maken aan de ORDER BY, maar welke aanpassing is dat precies? In dit korte artikel laten we je zien hoe je dit voor elkaar krijgt aan de hand van een voorbeeld.

We nemen daarbij het voorbeeld van twee gelinkte tabellen, een bewoner en een stad. Iedere bewoner kan gekoppeld zijn aan een bepaalde stad, maar dit hoeft niet. Met andere woorden: er zijn bewoner die niet gekoppeld zijn aan een stad. Dit levert de volgende tabellen op:

stad
stadId stad
1 Amersfoort
2 Zwolle
bewoner
bewonerId stadID bewoner
1 1 Marcel
2 Henk
3 2 Kees
4 2 Suzanne

Je ziet hier dat stad 2 (Zwolle) 2 bewoners heeft (Kees en Suzanne), en stad 1 (Amersfoort) 1 bewoner (Marcel). Alleen Henk is niet gekoppeld aan een stad.

Stel dat ik een overzicht van steden wil met per stad het aantal bewoners, met daarbij ook een regel van het aantal bewoners zonder stad. In dat geval zou mijn query er ongeveer als volgt uitzien:


SELECT			stad, COUNT(bewonerId) AS aantalBewoners
FROM				bewoner
						LEFT OUTER JOIN stad ON bewoner.stadId = stad.stadId
GROUP BY		stad
ORDER BY			stad ASC
			

In dit geval zien de resultaten er meteen redelijk uit, maar het grote nadeel is dat we niet kunnen sturen waar de regel met bewoners zonder stad zich in de resultaatset bevindt (en waarbij dus de kolom stad de waarde NULL bevat). Met andere woorden: we zouden graag eerst willen sorteren op deze regel, en dan pas op de naam van de stad. Om dat te doen moeten we een CASE introduceren in de ORDER BY, en wel als volgt:


SELECT			stad, COUNT(bewonerId) AS aantalBewoners
FROM				bewoner
						LEFT OUTER JOIN stad ON bewoner.stadId = stad.stadId
GROUP BY		stad
ORDER BY			CASE WHEN stad IS NULL THEN 1 ELSE 0 END ASC
					, stad ASC
			

Hiermee zorg je ervoor dat de regel met bewoners zonder stad altijd als eerste wordt vermeld in de resultaatset. Wil je deze regel juist als laatste, dan vervang je natuurlijk gewoon de ASC direct na het CASE statement in DESC.

Klein nadeel is dat de kolom Stad in die regel geen waarde bevat, maar NULL. Voor een grafiek kan dat bijvoorbeeld ongewenst zijn. In dat geval kun je de query nog als volgt aanpassen:


SELECT			ISNULL(stad,'onbekend') AS stad
					, COUNT(bewonerId) AS aantalBewoners
FROM				bewoner
						LEFT OUTER JOIN stad ON bewoner.stadId = stad.stadId
GROUP BY		stad
ORDER BY			CASE WHEN stad IS NULL THEN 1 ELSE 0 END ASC
					, stad ASC
			
Over mij

Mijn naam is Marcel van Langen. Ik ben werkzaam als freelancer. Een harde en eerlijke werker, met een passie voor doelgerichte oplossingen. Ik voer al jaren mooie klussen uit voor geweldige klanten. Mijn technische specialisaties zijn het Thinkwise platform, SQL Server en ColdFusion development.

Lees verder...
Diensten