Direct naar de hoofdinhoud
Module 3 · Les 3 van 411/57 in de cursus~10 min
Modulelessen (3/4)

Groeperen met GROUP BY

In Module 2 heb je geleerd dat COUNT(*), AVG(...), SUM(...) alle rijen naar een enkele resultaatrij. Maar wat als je een gemiddeld salaris wilt? voor elke afdeling, niet voor het hele bedrijf? U wilt één rij per groep. Dat is de taak van GROUP BY.

De syntaxis

SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM   table
GROUP BY grouping_column;

Lees in het Engels: "splits de rijen in groepen die dezelfde waarde delen van grouping_column, en bereken voor elke groep het totaal ".

SQL
-- Average salary per department:
SELECT department_id, AVG(salary) AS average
FROM   employees
GROUP BY department_id;

Het resultaat bevat één rij voor elke afzonderlijke department_id gevonden in BESCHERMD_INLINE_6. Je krijgt 5 rijen: één voor elk van de 4 afdelingen (1, 2, 3, 4) plus één voor NULL (Andrea Costa).

Met JOIN voor leesbare namen

Vaak wilt u groeperen op department_id, maar toont u de naam van de afdeling. Je combineert GROUP BY met een JOIN:

SQL
SELECT d.name AS department,
       COUNT(*)    AS count,
       AVG(e.salary) AS average_salary
FROM   employees   AS e
JOIN   departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;

Dit is een volwaardige business intelligence-query: in drie regels vertelt u hoeveel medewerkers elke afdeling heeft en hoeveel ze verdienen gemiddeld, gesorteerd van groot naar klein.

De gouden regel

Wanneer u GROUP BY gebruikt, moet elke kolom in SELECT zijn:

  1. een van de groeperingskolommen (bijvoorbeeld department_id, d.name), of
  2. binnen een aggregatiefunctie (bijvoorbeeld AVG(salary), COUNT(*)).
SQL
-- ERROR: first_name is neither in GROUP BY nor inside an aggregate
SELECT department_id, first_name, AVG(salary)
FROM   employees
GROUP BY department_id;

PostgreSQL retourneert een expliciete fout ("kolom moet verschijnen in het bestand GROUP BY clausule of worden gebruikt in een aggregatiefunctie"). Het is een gebruikelijke vroege week fout: als je het ziet, stop dan en vraag jezelf af: wat is de waarde ervan first_name voor een groep van 3 personen?"_ — er is geen eenduidig antwoord, en daarom weigert de motor.

Probeer het

Oefening#sql.m3.l3.e1
Pogingen: 0Laden…

Bereken voor elke afdeling hoeveel medewerkers deze bevat. Retourneer twee kolommen: de afdelingsnaam (departments.name) en het aantal werknemers. Eén rij per afdeling.

Editor laden…
Toon hint

Aggregeren met COUNT(*) en groeperen op d.name. De SELECT mag alleen de groeperingskolom en de aggregatie bevatten.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m3.l3.e2
Pogingen: 0Laden…

Bereken voor elke afdeling (departments.name) het gemiddelde salaris (AVG(salaris)) van de medewerkers, gesorteerd van hoog naar laag.

Editor laden…
Toon hint

AVG(e.salaris) als totaal, GROEP OP d.naam, ORDER OP gemiddelde DESC.

Oplossing beschikbaar na 3 pogingen