Cum funcționează
Cele două cerințe sunt aceeași interogare, o dată fără GROUP BY și o dată cu. Merită privite
una lângă alta, pentru că diferența dintre ele e tot ce înseamnă gruparea:
|
Cerința a) |
Cerința b) |
SELECT |
SUM(valoare) |
nume, SUM(valoare) |
GROUP BY |
— |
r.nume |
| Rezultat |
1 rând: totalul |
câte un rând per restaurant |
Fără GROUP BY, SUM strânge tot tabelul într-o singură valoare. Cu GROUP BY r.nume, tabelul se
împarte mai întâi în grămăjoare după restaurant, iar SUM se calculează separat în fiecare.
Ordinea clauzelor nu e o convenție, e ordinea de execuție
FROM + JOIN -> lipeste tabelele
WHERE -> arunca randurile care nu trec conditia (aici: status != 'LIVRATA')
GROUP BY -> aseaza ce a ramas in grupuri
SUM -> calculeaza in fiecare grup
ORDER BY -> sorteaza rezultatul final
De aici rezultă o regulă practică: WHERE filtrează rândurile de intrare, HAVING filtrează
grupurile de ieșire. Aici condiția e pe statusul unei comenzi (un rând), deci WHERE. Dacă s-ar
cere „restaurantele care au încasat peste 200", condiția ar fi pe rezultatul lui SUM, deci
HAVING SUM(c.valoare) > 200.
SUM și valorile lipsă
SUM ignoră NULL. O comandă cu valoarea necompletată nu contribuie cu 0 — pur și simplu nu intră
în sumă. Diferența se vede dacă compari COUNT(*) cu COUNT(valoare).
Statusul se scrie cu majuscule pentru că așa apare în date ('LIVRATA'). În Oracle, 'Livrata'
n-ar potrivi nimic.
Greșeli frecvente
GROUP BY uitat la b) — un singur total în loc de câte unul pe restaurant. Rezultatul e un
număr corect... la altă întrebare.
SELECT r.nume, SUM(c.valoare) fără GROUP BY — eroare în Oracle (not a single-group group
function); în MySQL/SQLite, un nume arbitrar lângă totalul general.
HAVING status = 'LIVRATA' în loc de WHERE — în unele sisteme merge, dar filtrează după
grupare și e greșit conceptual.
COUNT în loc de SUM — „suma totală a comenzilor" e suma valorilor, nu numărul lor.
'livrata' cu literă mică — zero rânduri în Oracle, deci SUM întoarce NULL.
GROUP BY r.idr cu SELECT r.nume — în Oracle dă eroare, pentru că nume nu e nici agregat,
nici în GROUP BY. Grupează după exact ce afișezi.