За да започнете с:Не,
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);