Salt la conținutul principal
Modulul 3 · Lecția 3 din 411/57 în curs~10 min
Lecții din modul (3/4)

Gruparea cu GROUP BY

În modulul 2 ați învățat că COUNT(*), AVG(...), SUM(...) reduc toate rânduri la un un singur rând de rezultat. Dar dacă vrei un salariu mediu pentru fiecare departament, nu pentru întreaga companie? Vrei un rând per grup. Aceasta este treaba lui GROUP BY.

Sintaxa

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

Citiți în engleză: "împărțiți rândurile în grupuri care au aceeași valoare a grouping_column, iar pentru fiecare grup calculați agregatul".

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

Rezultatul are un rând pentru fiecare department_id distinct găsit în employees. Veți primi 5 rânduri: unul pentru fiecare dintre cele 4 departamente (1, 2, 3, 4) plus unul pentru NULL (Andrea Costa).

Cu JOIN pentru nume care pot fi citite

Deseori doriți să grupați după department_id, dar afișați numele departament. Combinați GROUP BY cu un 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;

Aceasta este o interogare completă de business intelligence: în trei rânduri vă spune câți angajați are fiecare departament și cu cât câștigă medie, sortate de la cel mai mare la cel mai mic.

Regula de aur

Când utilizați GROUP BY, fiecare coloană din SELECT trebuie să fie:

  1. una dintre coloanele de grupare (de exemplu, department_id, d.name) sau
  2. în interiorul unei funcții agregate (de exemplu, 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 returnează o eroare explicită (coloana "trebuie să apară în GROUP BY clauză sau să fie utilizat într-o funcție agregată"). Este o săptămână de început obișnuită greșeală: dacă o vezi, oprește-te și întreabă-te "care este valoarea first_name pentru un grup de 3 persoane?" — nu există un singur răspuns și de aceea motorul refuza.

Încearcă

Exercițiu#sql.m3.l3.e1
Încercări: 0Se încarcă…

Pentru fiecare departament, calculați câți angajați conține. Returnează două coloane: numele departamentului (departments.name) și numărul de angajați. Un rând pe departament.

Se încarcă editorul...
Afișează indiciu

Agregați cu COUNT(*) și grupați după d.nume. SELECT trebuie să conțină numai coloana de grupare și agregatul.

Soluție disponibilă după 3 încercări

Exercițiu de revizuire

Exercițiu#sql.m3.l3.e2
Încercări: 0Se încarcă…

Pentru fiecare departament (departments.name), calculați salariul mediu (AVG(salariu)) al angajaților săi, sortați de la cel mai mare la cel mai mic.

Se încarcă editorul...
Afișează indiciu

AVG(e.salary) ca agregat, GROUP BY d.name, ORDER BY medie DESC.

Soluție disponibilă după 3 încercări