За да започнете с:Не,
SELECT user_id, MAX(salary) FROM users;
не е съвместим със стандарта. Използвате агрегатна функция (MAX
) без GROUP BY
клауза. По този начин казвате на СУБД да агрегира всички записи в един единствен ред с резултати. Сега какво казвате на СУБД да покаже в този ред с резултати? Максималната заплата, намерена в таблицата (MAX(salary)
) и на user_id
. Няма обаче на user_id
; вероятно има много различни user_id
на масата. Това нарушава стандарта SQL. MySQL си дава свободата да интерпретира неагрегирания user_id
като всякакви user_id
(произволно избран).
Така че, въпреки че заявката се изпълнява, нейният резултат обикновено не е желаният.
Тази заявка:
SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id;
от друга страна е съвместим със стандартите. Нека отново да видим какво прави тази заявка:Този път има GROUP BY
клауза, която казва на СУБД, че искате един ред резултат на user_id
. За всеки user_id
искате да покажете:the user_id
, на name
, и максималната salary
. Всичко това са валидни изрази; на user_id
е user_id
себе си, на name е единственото потребителско име, свързано с user_id
и максималната salary
е максималната заплата на потребителя. Неагрегираната колона name
е разрешено, тъй като е функционално зависимо от групирания по user_id
. Много СУБД обаче не поддържат това, тъй като може да стане изключително сложно да се определи дали изразът е функционално зависим от групата или не.
Що се отнася до това как да покажете потребителския запис с максималната заплата, имате нужда от ограничителна клауза. MySQL предоставя LIMIT
за това, което може да ви осигури първите n реда. Това обаче не се занимава с връзки.
SELECT * FROM users ORDER BY salary DESC LIMIT 1;
е
SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY;
в стандартен SQL.
За да се справите с връзките обаче, както в
SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES;
имате нужда от подзаявка в MySQL, защото LIMIT
не поддържа това:
SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);