Cum funcționează
a) „Din fiecare” = GROUP BY
Cuvântul care schimbă totul e „fiecare". Fără el, COUNT(*) întoarce un singur număr (vezi
problema #122). Cu el, se cere
câte un rând pe fiecare departament, iar asta se obține doar cu GROUP BY:
GROUP BY d.denumire -> rândurile se așează în grămăjoare după departament,
apoi COUNT numără fiecare grămăjoară separat
Regula care nu se încalcă niciodată: tot ce apare în SELECT și nu e într-o funcție de agregare
trebuie să apară în GROUP BY. Aici d.denumire e afișat simplu, deci e și în GROUP BY;
COUNT(a.ida) e agregat, deci nu.
De ce LEFT JOIN și nu INNER JOIN
INNER JOIN păstrează doar rândurile care au corespondent în ambele tabele. Un departament
nou-înființat, fără angajați, n-are nicio linie în Angajati — deci dispare complet din rezultat.
Răspunsul pare corect, doar că îi lipsește un rând.
LEFT JOIN păstrează toate rândurile din tabelul scris primul (Departamente) și completează
cu NULL acolo unde nu găsește potrivire. Pe datele de test, departamentul Marketing apare cu 0.
Și aici intervine al doilea detaliu: se scrie COUNT(a.ida), nu COUNT(*).
| Scris |
Ce dă pentru un departament fără angajați |
COUNT(*) |
1 — numără rândul produs de LEFT JOIN, cel plin de NULL |
COUNT(a.ida) |
0 — corect: COUNT pe o coloană ignoră NULL-urile |
Un „1" în loc de „0", pentru un departament gol. Exact tipul de greșeală care nu dă nicio eroare.
b) Doar o coloană în plus
Cerința b) e cea de la problema #122
cu nr_telefon adăugat. Telefonul e varchar2(12), nu număr — corect, pentru că un număr de telefon
începe cu 0, iar într-un câmp numeric zeroul din față se pierde.
Greșeli frecvente
COUNT(*) cu LEFT JOIN — departamentele goale ies cu 1 în loc de 0.
INNER JOIN la cerința „fiecare departament" — departamentele fără angajați dispar de tot.
SELECT d.denumire, COUNT(*) fără GROUP BY — eroare în Oracle; în MySQL/SQLite merge și
afișează un singur rând cu un nume ales la întâmplare.
GROUP BY pe a.idd în loc de d.denumire — grupează corect, dar afișează codul (D01), nu
denumirea cerută.
GROUP BY pus după ORDER BY — eroare de sintaxă; ordinea e GROUP BY, apoi ORDER BY.
WHERE folosit pentru a filtra rezultatul numărării — condițiile pe agregate se scriu cu
HAVING (ex. HAVING COUNT(a.ida) > 2), nu cu WHERE.