Cum funcționează
Cele două cerințe sunt cele două jumătăți ale aceluiași tipar, puse una lângă alta — motiv bun să se
înțeleagă diferența:
|
Cerința a) |
Cerința b) |
| Întrebarea |
cât e maximul? |
cine are maximul? |
| Instrucțiunea |
MAX(scor) |
WHERE scor = (SELECT MAX(scor) ...) |
| Rezultatul |
un număr |
unul sau mai multe rânduri |
MAX strânge toate rândurile într-unul singur, deci pierde username-ul și denumirea. Ca să afișezi
rândul, maximul trebuie calculat separat, într-o subinterogare, și comparat. Explicația completă, cu
toate variantele greșite, e la
problema #127.
Scurt, ce nu merge:
SELECT j.username, g.denumire, MAX(g.scor) FROM ... -- eroare in Oracle, rand arbitrar in MySQL
SELECT ... ORDER BY g.scor DESC; -- si se ia primul rand: pierzi egalitatile
Subinterogarea rămâne pe Jocuri, deși interogarea principală lipește două tabele: MAX(scor) e
scorul maxim din toată baza, nu „maximul per jucător". Subinterogarea e o întrebare separată, la care
se răspunde o singură dată, înainte.
Dacă s-ar cere scorul maxim al fiecărui jucător (altă cerință, ușor de confundat), răspunsul ar fi
o grupare, nu o subinterogare:
SELECT j.username, MAX(g.scor) AS scor_maxim
FROM Jucatori j INNER JOIN Jocuri g ON j.idj = g.idj
GROUP BY j.username;
Am adăugat g.scor în SELECT la b), deși nu e cerut explicit: fără el nu se vede despre ce scor e
vorba.
Greșeli frecvente
SELECT j.username, MAX(g.scor) fără GROUP BY — eroare în Oracle; în MySQL/SQLite,
maximul lângă un username arbitrar. Rezultat credibil și greșit.
ORDER BY g.scor DESC + primul rând — pierzi jocurile aflate la egalitate pe maxim.
WHERE g.scor = MAX(g.scor) — agregările nu se pot folosi direct în WHERE.
MAX(nivel) în loc de MAX(scor) — nivelul e al jucătorului, scorul e al jocului. Vezi
problema #156 pentru cerința pe
nivel.
- Subinterogare pe tabelul greșit —
(SELECT MAX(scor) FROM Jucatori): coloana nu există acolo.
- Confuzia cu „maximul fiecărui jucător" — aceea e o grupare (
GROUP BY), nu o subinterogare.