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

mostrar o último comentário que apenas 1 comentário por usuário

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 BY cláusula;
  • são usados ​​com GROUP BY funções agregadas ;
  • são funcionalmente dependentes das colunas que aparecem no GROUP BY clá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.