Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

SQL seleciona apenas linhas com valor máximo em uma coluna

À primeira vista...


Tudo que você precisa é de um GROUP BY cláusula com o MAX função agregada:
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

Nunca é tão simples, não é?


Acabei de perceber que você precisa do content coluna também.

Esta é uma pergunta muito comum em SQL:encontre todos os dados para a linha com algum valor máximo em uma coluna por algum identificador de grupo. Ouvi muito isso durante a minha carreira. Na verdade, foi uma das perguntas que respondi na entrevista técnica do meu trabalho atual.

Na verdade, é tão comum que a comunidade do Stack Overflow tenha criado uma única tag apenas para lidar com perguntas como essa: .

Basicamente, você tem duas abordagens para resolver esse problema:

Juntar-se com group-identifier, max-value-in-group simples Subconsulta


Nesta abordagem, você primeiro encontra o group-identifier, max-value-in-group (já resolvido acima) em uma subconsulta. Então você junta sua tabela à subconsulta com igualdade em ambos group-identifier e max-value-in-group :
SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM YourTable
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev

Left Joining with self, ajustando as condições de junção e filtros


Nesta abordagem, você deixou de juntar a tabela consigo mesma. A igualdade vai no group-identifier . Então, 2 movimentos inteligentes:
  1. A segunda condição de junção é ter o valor do lado esquerdo menor que o valor da direita
  2. Quando você executa a etapa 1, as linhas que realmente têm o valor máximo terão NULL no lado direito (é um LEFT JOIN , lembrar?). Em seguida, filtramos o resultado combinado, mostrando apenas as linhas em que o lado direito é NULL .

Então você acaba com:
SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

Conclusão


Ambas as abordagens trazem exatamente o mesmo resultado.

Se você tiver duas linhas com max-value-in-group para group-identifier , ambas as linhas estarão no resultado em ambas as abordagens.

Ambas as abordagens são compatíveis com SQL ANSI, portanto, funcionarão com seu RDBMS favorito, independentemente de seu "sabor".

Ambas as abordagens também são amigáveis ​​ao desempenho, no entanto, sua milhagem pode variar (RDBMS, estrutura de banco de dados, índices, etc.). Então, quando você escolhe uma abordagem em vez da outra, benchmark . E certifique-se de escolher aquele que faz mais sentido para você.