Pour commencer :Non,
SELECT user_id, MAX(salary) FROM users;
n'est pas conforme aux normes. Vous utilisez une fonction d'agrégation (MAX
) sans GROUP BY
clause. Ce faisant, vous dites au SGBD d'agréger tous les enregistrements en une seule ligne de résultat. Maintenant, que dites-vous au SGBD d'afficher dans cette ligne de résultat ? Le salaire maximum trouvé dans le tableau (MAX(salary)
) et le user_id
. Cependant, il n'y a pas le user_id
; il existe peut-être de nombreux user_id
différents dans la table. Cela viole la norme SQL. MySQL prend la liberté d'interpréter le user_id
non agrégé comme tout user_id
(choisi arbitrairement).
Ainsi, même si la requête s'exécute, son résultat n'est généralement pas celui souhaité.
Cette requête :
SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id;
d'autre part est conforme aux normes. Voyons à nouveau ce que fait cette requête :cette fois, il y a un GROUP BY
clause indiquant au SGBD que vous voulez une ligne de résultat par user_id
. Pour chaque user_id
vous voulez montrer :le user_id
, le name
, et le salary
maximum . Toutes ces expressions sont valides ; le user_id
est le user_id
lui-même, le name est le seul nom d'utilisateur associé au user_id
, et le salary
maximum est le salaire maximum de l'utilisateur. La colonne non agrégée name
est autorisé, car il dépend fonctionnellement du user_id
groupé par . Cependant, de nombreux SGBD ne le prennent pas en charge, car il peut être extrêmement compliqué de déterminer si une expression dépend fonctionnellement du groupe ou non.
Quant à savoir comment afficher l'enregistrement de l'utilisateur avec le salaire maximum, vous avez besoin d'une clause limitative. MySQL fournit LIMIT
pour cela, ce qui peut vous donner les n premières lignes. Il ne traite pas des liens cependant.
SELECT * FROM users ORDER BY salary DESC LIMIT 1;
est
SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY;
en SQL standard.
Afin de gérer les liens, cependant, comme dans
SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES;
vous avez besoin d'une sous-requête dans MySQL, car LIMIT
ne prend pas en charge ceci :
SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);