Por que não funciona com GROUP BY
SELECT * não pode ser usado com GROUP BY; é SQL inválido. GROUP BY não seleciona linhas da tabela. Ele cria grupos de linhas usando as expressões fornecidas e, a partir de cada grupo, gera um novo registro e calcula cada coluna desse novo registro usando os valores envolvidos na expressão. As colunas que aparecem no
SELECT cláusula deve satisfazer uma das seguintes regras:- também aparecem em
GROUP BYcláusula; - são usados com
GROUP BYfunções agregadas ; - são funcionalmente dependentes das colunas que aparecem no
GROUP BYcláusula.
Enquanto
* é um atalho para todos os nomes de coluna da(s) tabela(s) usada(s) pela consulta, para sua consulta apenas o user coluna satisfaça um dos requisitos acima. Antes da versão 5.7.5 O MySQL não implementou a terceira regra acima. Ele costumava aceitar consultas que continham no
SELECT colunas de cláusulas que não seguem nenhuma das cláusulas GROUP BY requisitos. O valor retornado pela consulta para essas colunas foi indeterminado
. Desde a versão 5.7.5, o MySQL rejeita o
GROUP BY consultas que satisfazem os requisitos. A solução
De qualquer forma, a solução para o seu problema não envolve
GROUP BY . Isso pode ser feito facilmente usando um LEFT JOIN com as condições corretas:SELECT lc.*
FROM comments lc # 'lc' from 'last comment'
LEFT JOIN comments nc # 'nc' from 'newer comment'
ON lc.user = nc.user # both comments belong to the same user
AND lc.id < nc.id # 'nc' is newer than 'lc'
WHERE nc.id IS NULL # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10
Como funciona
Ele se junta à tabela
comments , alias como lc ("lc" do "último comentário" de um usuário) contra si mesmo, alias como nc ("nc" de "comentário mais recente"). A cláusula join corresponde a cada entrada de lc com todas as entradas de nc que pertencem ao mesmo usuário (lc.user = nc.user ) e são mais recentes (lc.id < nc.id; Presumi que os IDs são atribuídos sequencialmente e os comentários mais recentes têm valores maiores para id ). O uso de
LEFT JOIN garante que cada linha de lc aparece no resultado da junção, mesmo quando nenhuma linha correspondente é encontrada em nc (porque não há comentários mais recentes do mesmo usuário). Neste caso, NULL é usado em vez dos campos de nc . O WHERE cláusula mantém no resultado final apenas as linhas que possuem NULL em nc.id; isso significa que no lc parte eles contêm o comentário mais recente de cada usuário. O
SELECT cláusula contém todos os campos de lc (os de nc são todos NULL , de qualquer forma). O ORDER BY cláusula pode ser usada para classificar o conjunto de resultados. ORDER BY lc.id DESC coloca os comentários mais recentes primeiro e o LIMIT cláusula mantém o resultado definido em um tamanho decente.