Everybody in this country should learn to program a computer, because it teaches you how to think.
—Steve Jobs

De ORDER BY clause in detail

Als je met een SELECT query als resultaat een aantal rijen krijgt, is de volgorde waarin die getoond worden onvoorspelbaar. De enige manier om een bepaalde volgorde te bekomen, is gebruik te maken van de ORDER BY clause.

Je kan de query's nog steeds uitvoeren op de tabel ‘opleidingsonderdeel’ in het schema ‘uclloket’ van de databank ‘df’ of in je eigen versie hiervan.

Sorteren op kolommen

Op kolomnaam

De volgende query toont drie kolommen voor alle OPO’s die minder dan 6 SP hebben:

SELECT opocode, studiepunten, naam
FROM opleidingsonderdeel
WHERE studiepunten < 6

Zoals gezegd kan je op voorhand niets zeggen over de volgorde waarin deze rijen getoond worden. Als je de rijen gesorteerd wil zodat de studiepunten van klein naar groot gerangschikt staan, kan dat door de kolomhoofding in de ORDER BY clause te gebruiken:

SELECT opocode, studiepunten, naam
FROM opleidingsonderdeel
WHERE studiepunten < 6
ORDER BY studiepunten ASC

De toevoeging ASC (‘ascending’) mag weggelaten worden, want dat is de standaardsortering.

Omdat het zo belangrijk is, overlopen we nog eens de volgorde waarin deze query uitgevoerd wordt:

  1. Eerst de FROM: welke tabel(len) moeten in het werkgeheugen geladen worden?
  2. Daarna WHERE: enkel de rijen die aan deze voorwaarde voldoen blijven bewaard, de rest wordt verwijderd.
  3. Vervolgens de GROUP BY, onmiddellijk gevolgd door HAVING. Deze twee clauses zijn niet aanwezig in dit voorbeeld.
  4. Dan pas komt de SELECT clause: welke kolommen moeten getoond worden?
  5. Tot slot de ORDER BY: in welke volgorde worden de rijen getoond?

Dit is het resultaat van de query:

orden volgens stijgend aantal studiepunten

De OPO’s met het kleinste aantal SP staan bovenaan. Binnen de rijen met de zelfde waarde voor het aantal SP (bvb 3) is de volgorde nog steeds onvoorspelbaar. Je kan echter meer dan één kolom aangeven om op te sorteren. Stel dat je eerst wil sorteren op stijgend aantal SP en daarna (binnen rijen met hetzelfde aantal SP) alfabetisch op naam, dan kan dat als volgt:

SELECT opocode, studiepunten, naam
FROM opleidingsonderdeel
WHERE studiepunten < 6
ORDER BY studiepunten, naam

Dit is het resultaat:

orden volgens stijgend aantal studiepunten en dan naam

Merk op dat de volgorde belangrijk is: ORDER BY studiepunten, naam geeft een ander resultaat dan ORDER BY naam, studiepunten!

Op volgnummer van de kolom

Zoals zo vaak in SQL bestaat er een kortere manier om dingen te noteren. Nemen we als voorbeeld de laatste query:

SELECT opocode, studiepunten, naam
FROM opleidingsonderdeel
WHERE studiepunten < 6
ORDER BY studiepunten, naam

Een korter alternatief is om de kolomnummers van de kolommen uit de SELECT gebruiken i.p.v. de naam:

SELECT opocode, studiepunten, naam
FROM opleidingsonderdeel
WHERE studiepunten < 6
ORDER BY 2, 3

Je moet dan vanzelfsprekend weten wat de kolomnummers zijn in de SELECT. Een klein nadeel is dat je de kolomnummers moet aanpassen als je besluit in de SELECT clause een extra kolom toe te voegen, zoals in deze uitgebreide query:

SELECT opocode, coordinator, studiepunten, naam -- extra tweede kolom
FROM opleidingsonderdeel
WHERE studiepunten < 6
ORDER BY 3, 4 -- de kolomnummers schuiven eentje op

Oplopend en aflopend sorteren

Met ASC sorteer je van klein naar groot. Dit is ook de standaardwaarde, dus je mag dit weglaten. Sorteren van groot naar klein doe je met DESC. Zeker als Nederlands niet je moedertaal is, kan het een uitdaging zijn om uit de opgave de juiste sorteervolgorde te halen. We hebben immers in taal veel verschillende manieren om ongeveer hetzelfde te zeggen. Een klein overzichtje met enkele mogelijkheden:

Sorteren op uitdrukkingen

Je weet al dat je zelf nieuwe kolommen kan bijmaken (zie hoofdstuk SELECT). Hetzelfde kan je doen in de ORDER BY clause zoals volgend voorbeeld toont:

SELECT opocode, coordinator, studiepunten, naam
FROM opleidingsonderdeel
ORDER BY
  CASE
    WHEN studiepunten <= 6 THEN 'gewoon'
    ELSE 'speciaal'
  END

Je kan het vergelijken met een nieuwe kolom bijmaken (zet zelf de CASE eens in de SELECT) en dan sorteren op deze niet-getoonde kolom. Deze query geeft alle OPO’s van 6 of minder SP de waarde ‘gewoon’ en alle grotere OPO’s de waarde ‘speciaal’. Op deze twee waarden wordt er dan gesorteerd. Omdat ‘speciaal’ in alfabetische volgorde later komt dan ‘gewoon’ zullen alle OPO’s met 6 of minder SP bovenaan de lijst staan.

Een tweede voorbeeld: de laatste letter van de OPOcode heeft vaak een speciale betekenis. Volgende query laat toe om te sorteren op deze laatste letter (‘A’, ‘H’ enz):

SELECT opocode, coordinator, studiepunten, naam
FROM opleidingsonderdeel
ORDER BY substring(opocode FROM 6) -- alle letters vanaf de 6de, dus enkel de laatste letter

Wat met NULL waarden?

Zoals al uitgelegd in de oplossing van de eerste oefening op de CSV-dataset legt de SQL-standaard niet vast wat er moet gebeuren met NULL waarden in een kolom waarop gesorteerd wordt. PostgreSQL beschouwt NULL als een waarde groter dan alle andere waarden en dus komen rijen met deze waarde in de kolom onderaan de lijst te staan. Er zijn andere databanksystemen die het omgekeerd doen …

Oefeningen

Geef een overzicht van alle OPOs alfabetisch gesorteerd op coördinator en voor elke coördinator oplopend gesorteerd op semester.

SELECT naam, coordinator, semester
FROM opleidingsonderdeel
ORDER BY coordinator ASC, semester ASC;

Sorteer de OPOs op basis van hoe lang ze al gegeven worden. De OPOs die al het langst gegeven worden staan bovenaan. Als de einddatum NULL is, mag je het aantal jaar gelijk stellen aan 1.

SELECT naam, van, tot,
  CASE
    WHEN tot IS NULL THEN 1
     ELSE(tot - van) / 365.25       -- Om de 4 jaar een schrikkeljaar, niet exact, maar OK
  END AS AANTAL_JAAR_GEGEVEN
FROM opleidingsonderdeel
ORDER BY 4 DESC;

Extra uitdaging voor de dapperen, stel ‘tot’ gelijk aan de einddatum van het huidige academiejaar indien ‘tot IS NULL’ en reken daarmee verder.

Oefeningen SQLzoo

Tabel Nobelprijswinnaars

Een overzicht van Nobelprijswinnaars met volgende kolommen:

Oefeningenreeks 3 bevat vooral oefeningen op WHERE. Bij de laatste oefeningen moet je ook ORDER BY gebruiken.

Maak nu quiz 3 op de tabel met de Nobelprijswinnaars.