
Groeperen met GROUP BY
Introductie
Inmiddels weten we hoe we alle data uit een tabel moeten selecteren:
| id | name | year | rank |
|---|---|---|---|
| 10920 | Aliens | 1986 | 8.2 |
| 17173 | Animal House | 1978 | 7.5 |
| 18979 | Apollo 13 | 1995 | 7.5 |
| ... | ... | ... | ... |
Met functie COUNT() kunnen we berekenen hoeveel rijen er zijn:
| count |
|---|
| 36 |
Nu zou het handig zijn om bijvoorbeeld te berekenen hoeveel films er per jaartal zijn uitgekomen.
- Daarvoor zouden we per uniek jaartal het aantal rijen moeten tellen.
- Dit kan met
GROUP BY.
1. GROUP BY voorbeeld
Dit doen we in het volgende voorbeeld:
| year | count |
|---|---|
| 1989 | 2 |
| 1991 | 1 |
| 1977 | 1 |
| ... | ... |
- We selecteren uit tabel
movieskolomyear, en metCOUNT(*)tellen we de rijen. - Met
GROUP BYgroeperen we op kolomyear. - Hierdoor zien we het aantal films wat uit elk van de voorkomende jaartallen.
- De nieuwe kolom krijgt standaard de naam
count.
Als we COUNT(*) niet toevoegen, zien we alleen de unieke jaartallen:
| year |
|---|
| 1989 |
| 1991 |
| 1977 |
| ... |
- Je moet dus altijd benoemen wat je doet na het groeperen.
2. Groeperen en andere SQL statements
We weten nu dat we met GROUP BY kunnen groeperen.
Echter, het resultaat zag er nog niet direct erg overzichtelijk uit.
- Het zou mooier zijn als er bijvoorbeeld op jaartal of aantal films gesorteerd kan worden.
Uiteraard kan dit.
We bekijken het in het volgende voorbeeld:
| year | count |
|---|---|
| 2005 | 1 |
| 2004 | 2 |
| 2003 | 4 |
| ... | ... |
ORDER BYkan eenvoudig toegevoegd worden om een sortering toe te passen.
We kunnen ook op het aantal films per jaar sorteren:
| year | count |
|---|---|
| 1977 | 1 |
| 1986 | 1 |
| 1972 | 1 |
| ... | ... |
| 1989 | 2 |
| ... | ... |
| 2001 | 3 |
| ... | ... |
- Hiermee zie je eenvoudig in welke jaartallen de meeste/minste films zijn gemaakt.
3. Een nieuwe kolom vanuit GROUP BY een naam geven met AS
We weten nu dat we met GROUP BY kunnen groeperen.
Standaard krijgt de kolom vanuit COUNT(*) de naam count.
Met AS kunnen we de kolom een andere naam (alias) geven.
We bekijken het in het volgende voorbeeld:
| year | count_movies |
|---|---|
| 1989 | 2 |
| 1991 | 1 |
| 1977 | 1 |
| ... | ... |
- Met
ASgeven we de nieuwe kolom de naamcount_movies.
Let op: in sommige SQL dialecten gebruik je het
=teken inplaats vanAS.
4. Filteren na groeperen met HAVING
We hebben gegroepeerd op jaartal.
Hiermee weten we het aantal films per jaar.
We weten dat we met het WHERE statement kunnen filteren.
Intuitief zouden we daardoor op de volgende code kunnen komen:
Dit geeft echter een error:
Deze error komt door de volgorde waarin vanuit SQL statements uitgevoerd worden.
WHEREwordt voorGROUP BYuitgevoerd. Je kan metWHEREdaarom alleen filteren op kolommen die in de geselecteerde tabellen zitten.- De kolom
COUNT(*) as count_movieszit niet in de geselecteerde tabel maar onstaat pas naGROUP BY.
Gelukkig is hier een oplossing voor.
- Met
HAVINGkun je wel naGROUP BYfilteren.
We bekijken dit in het volgende voorbeeld:
| year | count_movies |
|---|---|
| 2003 | 4 |
| 2000 | 4 |
| 2001 | 3 |
| 1999 | 4 |
- Dit werkt zoals verwacht.
- We zien nu alleen jaartallen waar het aantal films uit dat jaar groter is dan
2.
Om dezelfde reden dat we WHERE niet kunnen gebruiken, kunnen we ook de nieuwe naam (alias) niet gebruiken.
Deze is nog niet bekend als het HAVING statement uitgevoerd wordt.
Dit geeft een error:
Samenvatting
- Je kunt op unieke waarden uit een kolom groeperen.
- Hiervoor gebruik je
GROUP BY. - Met
COUNT(*)kun je het aantal rijen per unieke waarde tellen. - Bijvoorbeeld:
- Hiervoor gebruik je
- Na groeperen kun je bijvoorbeeld sorteren met
ORDER BY. - Na groeperen kun je de nieuwe kolom een specifieke naam (alias) geven met
AS. - Na groeperen kun je filteren met
HAVING.- Bijvoorbeeld:
- Door de volgorde waarin SQL statements uitvoert werkt het volgende niet:
- Filteren op een kolom die ontstaat door
GROUP BY(zoalsCOUNT(*)) metWHERE: je moetHAVINGgebruiken. - Een alias gebruiken om te sorteren of filteren: je moet de originele functie gebruiken, bijvoorbeeld
COUNT(*).
- Filteren op een kolom die ontstaat door