Para começar:Não,
SELECT user_id, MAX(salary) FROM users;
não é compatível com o padrão. Você está usando uma função agregada (
MAX
) sem um GROUP BY
cláusula. Ao fazer isso, você instrui o DBMS a agregar todos os registros a uma única linha de resultado. Agora, o que você diz ao DBMS para mostrar nesta linha de resultado? O salário máximo encontrado na tabela (MAX(salary)
) e o user_id
. No entanto, não existe o user_id
; possivelmente existem muitos user_id
diferentes na mesa. Isso viola o padrão SQL. O MySQL toma a liberdade de interpretar o user_id
não agregado como qualquer user_id
(escolhido arbitrariamente). Portanto, mesmo que a consulta seja executada, o resultado geralmente não é o desejado.
Esta consulta:
SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id;
por outro lado é compatível com o padrão. Vamos ver novamente o que esta consulta faz:Desta vez há um
GROUP BY
cláusula informando ao DBMS que você deseja uma linha de resultado por user_id
. Para cada user_id
você deseja mostrar:o user_id
, o name
, e o salary
máximo . Todas essas são expressões válidas; o user_id
é o user_id
em si, o name é o único nome de usuário associado ao user_id
, e o salary
máximo é o salário máximo do usuário. A coluna não agregada name
é permitido, porque é funcionalmente dependente do user_id
agrupado por . Muitos DBMS não suportam isso, porém, porque pode ser extremamente complicado determinar se uma expressão é funcionalmente dependente do grupo ou não. Quanto a como mostrar o cadastro do usuário com o salário máximo, você precisa de uma cláusula limitante. MySQL fornece
LIMIT
para isso, que pode obter as primeiras n linhas. Ele não lida com laços no entanto. SELECT * FROM users ORDER BY salary DESC LIMIT 1;
é
SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY;
em SQL padrão.
Para lidar com os laços, no entanto, como em
SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES;
você precisa de uma subconsulta no MySQL, porque
LIMIT
não suporta isso:SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);