Cum funcționează
Tiparul canonic e la tabelul Carti. Problema arată bine diferenţa
dintre a lista rânduri şi a le grupa.
Structura datelor: un rând = o masă într-o zi
Masa 1 apare de trei ori, câte o dată pentru fiecare zi. Nu e o eroare — tabelul reţine activitatea
zilnică, deci perechea (masă, dată) e cea care identifică un rând.
c) Listare, fără agregare
SELECT Data, Nr_comenzi FROM Mese WHERE Nr_masa = 1 ORDER BY Data ASC;
Enunțul cere „numărul comenzilor zilnice", deci fiecare zi separat — se listează rândurile aşa
cum sunt, fără SUM. Rezultat: 10 iulie (13), 11 iulie (8), 12 iulie (12).
Se afişează Data alături de Nr_comenzi, pentru că altfel trei numere fără context n-ar spune
nimic.
d) Agregare, cu GROUP BY
SELECT Nr_masa, SUM(Valoare_comenzi) FROM Mese WHERE ... GROUP BY Nr_masa;
Aici se cere o singură valoare pentru fiecare masă, deci rândurile aceleiaşi mese se comprimă:
Masa 1 -> 214 + 178 + 263 = 655
Masa 2 -> 567 + 481 = 1048
Masa 3 -> 358
Masa 4 -> 276
Din 7 rânduri ies 4.
Contrastul dintre c) şi d) e ideea de reţinut:
|
c) |
d) |
| Ce se cere |
fiecare zi separat |
un total pe masă |
| Rânduri în rezultat |
câte unul pe zi |
câte unul pe masă |
| Agregare |
nu |
SUM + GROUP BY |
Când enunțul spune „pentru fiecare X", aproape sigur ai nevoie de GROUP BY X.
WHERE înaintea grupării
Filtrul pe iulie 2020 se aplică înainte de grupare: se elimină rândurile nedorite, apoi se
adună ce a rămas. Aici toate datele sunt din iulie, deci filtrul nu schimbă rezultatul — dar e cerut
explicit şi ar conta la un tabel cu mai multe luni.
Pentru condiţii pe rezultatul agregării (de exemplu „mesele cu total peste 500") se foloseşte
HAVING, nu WHERE: GROUP BY Nr_masa HAVING SUM(Valoare_comenzi) > 500.
Greșeli frecvente
SUM la c) — se cere fiecare zi separat, nu totalul mesei 1.
GROUP BY uitat la d) — iese o singură sumă, pentru tot restaurantul.
SELECT Data, SUM(...) cu GROUP BY Nr_masa — Data nu e în gruparea.
Nr_locuri inclus în SELECT — nu e cerut şi ar cere să fie şi în GROUP BY.
HAVING şi WHERE confundate — WHERE filtrează rânduri, HAVING filtrează grupuri.