Cum funcționează
a) „În fiecare” = GROUP BY
Cuvântul „fiecare" cere un rând pe fiecare cinematograf, deci GROUP BY c.denumire. Fără el,
COUNT(*) ar da un singur număr: câte perechi film-cinematograf există în total.
Regula de aur a grupării: tot ce apare în SELECT și nu e agregat trebuie să fie în GROUP BY.
Aici c.denumire e afișată simplu → intră în GROUP BY; COUNT(f.idf) e agregat → nu.
De ce LEFT JOIN și COUNT(f.idf), nu COUNT(*)
Un cinematograf care nu difuzează niciun film n-are nicio linie în Filme. Cu INNER JOIN dispare
complet din rezultat — răspunsul pare corect, doar că îi lipsește un rând.
LEFT JOIN păstrează toate cinematografele și completează cu NULL unde nu găsește film. Iar atunci
alegerea dintre COUNT(*) și COUNT(f.idf) decide dacă răspunsul e corect:
| Scris |
Pentru un cinematograf fără filme |
COUNT(*) |
1 — numără rândul cu NULL-uri produs de joncțiune |
COUNT(f.idf) |
0 — COUNT pe o coloană ignoră NULL-urile |
Un „1" în loc de „0". Aceeași capcană, explicată pe alt exemplu, la
problema #128.
b) Filtrare simplă după joncțiune
Se cer două coloane din Filme, filtrate după denumirea cinematografului din Cinematografe. Pe
datele de test, Happy Cinema are două filme.
Dacă ai vrea doar cinematografele cu mai mult de două filme, condiția se pune pe rezultatul numărării,
deci cu HAVING:
GROUP BY c.denumire
HAVING COUNT(f.idf) > 2
Greșeli frecvente
COUNT(*) cu LEFT JOIN — cinematografele fără filme ies cu 1 în loc de 0.
INNER JOIN la cerința „fiecare cinematograf" — cinematografele fără filme dispar.
GROUP BY uitat — eroare în Oracle; în MySQL/SQLite, un singur rând cu o denumire la
întâmplare.
GROUP BY c.idc cu SELECT c.denumire — în Oracle e eroare. Grupează după exact ce afișezi.
WHERE COUNT(f.idf) > 2 — condițiile pe agregate se scriu cu HAVING.
'happy cinema' cu literă mică — în Oracle, zero rânduri.