Cum funcționează
a) COUNT(DISTINCT ...) — două operații într-una
Enunțul cere câte tipuri diferite există, nu câte restaurante. Dacă două restaurante au
bucătărie italiană, „italiana" se numără o singură dată:
| Scris |
Pe datele de test |
Ce numără |
COUNT(*) |
6 |
restaurantele |
COUNT(tip_bucatarie) |
6 |
restaurantele cu tipul completat |
COUNT(DISTINCT tip_bucatarie) |
5 |
tipurile diferite |
Diferența dintre 6 și 5 e un singur rând dublat — și toată diferența dintre răspuns corect și
răspuns greșit. Cuvântul din enunț care o cere e „distincte".
Dacă s-ar cere lista tipurilor, nu numărul lor: SELECT DISTINCT tip_bucatarie FROM Restaurante
(vezi problema #151, cerința a).
b) „Pentru fiecare” = GROUP BY
Al doilea cuvânt-cheie care schimbă interogarea: „fiecare". Se cere un rând per tip de bucătărie,
deci GROUP BY r.tip_bucatarie. Comenzile se numără separat în fiecare grup.
LEFT JOIN și COUNT(c.idc), nu COUNT(*) — exact ca la
problema #128:
LEFT JOIN păstrează tipurile de bucătărie ale restaurantelor fără nicio comandă
COUNT(c.idc) le arată cu 0; COUNT(*) ar arăta 1, numărând rândul gol produs de joncțiune
Observă că se grupează după o coloană din Restaurante, deși se numără rânduri din Comenzi. Asta e
posibil pentru că gruparea se face după lipirea tabelelor: la momentul acela, fiecare rând are și
tipul de bucătărie, și comanda.
Dacă ai vrea doar tipurile cu mai mult de două comenzi, condiția se pune cu HAVING, nu cu WHERE:
GROUP BY r.tip_bucatarie
HAVING COUNT(c.idc) > 2
WHERE filtrează rânduri înainte de grupare, HAVING filtrează grupuri după.
Greșeli frecvente
COUNT(*) în loc de COUNT(DISTINCT tip_bucatarie) — numeri restaurantele, nu tipurile. 6 în
loc de 5.
SELECT DISTINCT COUNT(tip_bucatarie) — numără tot, apoi elimină dublurile dintr-un rezultat
cu un singur rând. Nu schimbă nimic.
COUNT(*) cu LEFT JOIN — tipurile fără comenzi ies cu 1 în loc de 0.
GROUP BY uitat la b) — un singur număr, pentru toate comenzile la un loc.
GROUP BY r.nume în loc de r.tip_bucatarie — grupează pe restaurant, nu pe tip. Răspunde la
altă întrebare.
WHERE COUNT(c.idc) > 2 — condițiile pe agregate se scriu cu HAVING. WHERE dă eroare.