Om te beginnen:Nee,
SELECT user_id, MAX(salary) FROM users;
voldoet niet aan de norm. U gebruikt een aggregatiefunctie (MAX
) zonder een GROUP BY
clausule. Door dit te doen, geeft u het DBMS de opdracht om alle records samen te voegen tot één enkele resultaatrij. Wat vertel je de DBMS om in deze resultaatrij te tonen? Het maximale salaris in de tabel (MAX(salary)
) en de user_id
. Er is echter geen de user_id
; er zijn mogelijk veel verschillende user_id
in de tafel. Dit is in strijd met de SQL-standaard. MySQL neemt de vrijheid om de niet-geaggregeerde user_id
als elke user_id
(willekeurig gekozen).
Dus ook al wordt de query uitgevoerd, het resultaat is meestal niet het gewenste.
Deze vraag:
SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id;
aan de andere kant is normconform. Laten we nog eens kijken wat deze zoekopdracht doet:deze keer is er een GROUP BY
clausule die de DBMS vertelt dat u één resultaatrij per user_id
. wilt . Voor elke user_id
je wilt laten zien:de user_id
, de name
, en het maximale salary
. Dit zijn allemaal geldige uitdrukkingen; de user_id
is de user_id
zelf, de naam is de enige gebruikersnaam die is gekoppeld aan de user_id
, en het maximale salary
is het maximumsalaris van de gebruiker. De niet-geaggregeerde kolom name
is toegestaan, omdat het functioneel afhankelijk is van de gegroepeerde user_id
. Veel DBMS ondersteunen dit echter niet, omdat het extreem ingewikkeld kan worden om te bepalen of een expressie functioneel afhankelijk is van de groep of niet.
Voor het tonen van het gebruikersrecord met het maximale salaris heeft u een beperkingsclausule nodig. MySQL biedt LIMIT
hiervoor, waarmee u de eerste n rijen kunt krijgen. Het gaat echter niet over banden.
SELECT * FROM users ORDER BY salary DESC LIMIT 1;
is
SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY;
in standaard SQL.
Om echter met banden om te gaan, zoals in
SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES;
je hebt een subquery nodig in MySQL, omdat LIMIT
ondersteunt dit niet:
SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);