Till att börja med:Nej,
SELECT user_id, MAX(salary) FROM users;
är inte standard. Du använder en aggregatfunktion (MAX
) utan en GROUP BY
klausul. Genom att göra det säger du till DBMS att samla alla poster till en enda resultatrad. Vad säger du nu till DBMS att visa i den här resultatraden? Den maximala lönen som finns i tabellen (MAX(salary)
) och den user_id
. Det finns dock ingen den user_id
; det finns möjligen många olika user_id
i bordet. Detta bryter mot SQL-standarden. MySQL tar sig friheten att tolka det icke-aggregerade user_id
som alla user_id
(godtyckligt utvald).
Så även om frågan körs är resultatet vanligtvis inte det önskade.
Denna fråga:
SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id;
å andra sidan är standardkompatibel. Låt oss se igen vad den här frågan gör:Den här gången finns det en GROUP BY
klausul som talar om för DBMS att du vill ha en resultatrad per user_id
. För varje user_id
du vill visa:den user_id
, den name
och den maximala salary
. Alla dessa är giltiga uttryck; den user_id
är user_id
sig själv, den namn är det enda användarnamnet som är kopplat till user_id
och den maximala salary
är användarens maxlön. Den oaggregerade kolumnen name
är tillåtet eftersom det är funktionellt beroende av den grupperade efter user_id
. Många DBMS stöder dock inte detta, eftersom det kan bli extremt komplicerat att avgöra om ett uttryck är funktionellt beroende av gruppen eller inte.
Om hur man visar användarregistret med maxlönen behöver du en begränsningsklausul. MySQL tillhandahåller LIMIT
för detta, vilket kan ge dig de första n raderna. Det handlar dock inte om band.
SELECT * FROM users ORDER BY salary DESC LIMIT 1;
är
SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY;
i standard SQL.
Men för att hantera band, som i
SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES;
du behöver en underfråga i MySQL, eftersom LIMIT
stöder inte detta:
SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);