Cum funcționează
a) Tot tabelul, fără condiții
„Afișați departamentele din firmă" e cea mai simplă interogare posibilă. SELECT * ar fi acceptat;
enumerarea coloanelor e preferabilă, pentru că arată că știi ce conține tabelul.
b) Tiparul „cine are valoarea maximă” — de învățat o dată
Aceasta e construcția cea mai des cerută din tot Subiectul I, în zeci de variante („salariul maxim",
„comanda cu valoarea maximă", „filmul cu durata maximă", „scorul maxim"). Se rezolvă întotdeauna
la fel, în doi pași care se scriu într-o singură interogare:
SELECT MAX(salariul) FROM Angajati -- 1. cat e maximul? -> 5200
SELECT ... WHERE salariul = (rezultatul) -- 2. cine are exact atat?
Motivul pentru care nu se poate într-un singur pas: MAX strânge toate rândurile într-unul
singur, deci pierde numele. Odată strânse, nu mai există rând individual de afișat.
De aceea următoarea scriere, cea la care ajunge aproape toată lumea prima dată, e greșită:
SELECT nume, prenume, MAX(salariul) FROM Angajati; -- GREȘIT
În Oracle și în SQL Server dă eroare (not a single-group group function). În MySQL și SQLite, mai
rău: merge și afișează salariul maxim lângă un nume luat la întâmplare — de obicei al primului
rând din tabel. Un rezultat care arată perfect corect și e greșit.
Varianta cu sortare are altă problemă:
SELECT nume, prenume, salariul FROM Angajati ORDER BY salariul DESC; -- si iei primul rand
Dacă doi angajați au același salariu maxim, cerința („angajații care au salariul maxim") cere
amândoi, iar „primul rând" arată unul. Subinterogarea îi întoarce pe toți, oricâți sunt.
Aceeași construcție se folosește la
problema #134 (comanda cu valoarea
maximă), #147 (filmul cu durata
maximă) și #153 (scorul maxim). Cu MIN în
loc de MAX, rezolvă și „cel mai ieftin / cel mai mic".
Greșeli frecvente
SELECT nume, MAX(salariul) — eroare în Oracle, rezultat greșit dar credibil în MySQL și
SQLite. Cea mai periculoasă greșeală din categorie.
ORDER BY salariul DESC + primul rând — pierzi rândurile egale la maxim.
WHERE salariul = MAX(salariul) — agregările nu se pot folosi în WHERE. Îi trebuie
subinterogare.
WHERE salariul >= (SELECT MAX(...)) — corect ca rezultat, dar >= arată că nu ai înțeles că
nimic nu poate fi mai mare decât maximul.
- Subinterogare pe alt tabel decât trebuie —
(SELECT MAX(salariul) FROM Departamente): coloana
nu există acolo.
- Salariul uitat din
SELECT — cerința îl cere explicit: „numele, prenumele și salariul".