Mysql
 sql >> Database >  >> RDS >> Mysql

mostra l'ultimo commento che solo 1 commento per utente

Perché non funziona con GROUP BY

SELECT * non può essere utilizzato con GROUP BY; è SQL non valido. GROUP BY non seleziona le righe della tabella. Crea gruppi di righe utilizzando le espressioni fornite, quindi, da ciascun gruppo, genera un nuovo record e calcola ogni colonna di questo nuovo record utilizzando i valori coinvolti nell'espressione.

Le colonne che appaiono in SELECT la clausola deve soddisfare una delle seguenti regole:

  • appaiono anche nel GROUP BY clausola;
  • sono utilizzati con GROUP BY funzioni aggregate ;
  • dipendono dal punto di vista funzionale dalle colonne che appaiono nel GROUP BY clausola.

Mentre * è una scorciatoia per tutti i nomi di colonna delle tabelle utilizzate dalla query, per la tua query solo l'user colonna soddisfa uno dei requisiti di cui sopra.

Prima della versione 5.7.5 MySQL non ha implementato la terza regola sopra. Accettava query che contengono in SELECT colonne di clausole che non seguono nessuno dei GROUP BY requisiti. Il valore restituito dalla query per tali colonne era indeterminato .

Dalla versione 5.7.5, MySQL rifiuta il GROUP BY domande che soddisfano i requisiti.

La soluzione

In ogni caso, la soluzione al tuo problema non prevede GROUP BY . Può essere facilmente realizzato usando un LEFT JOIN con le condizioni corrette:

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

Come funziona

Si unisce alla tabella comments , alias lc ("lc" dall'"ultimo commento" di un utente) contro se stesso, alias nc ("nc" da "commento più recente"). La clausola join corrisponde a ogni voce di lc con tutte le voci di nc che appartengono allo stesso utente (lc.user = nc.user ) e sono più recenti (lc.id < nc.id; Presumo che gli ID vengano assegnati in sequenza e che i commenti più recenti abbiano valori maggiori per id ).

L'uso di LEFT JOIN assicura che ogni riga di lc appare nel risultato del join, anche quando non viene trovata alcuna riga corrispondente in nc (perché non ci sono commenti più recenti dello stesso utente). In questo caso, NULL viene utilizzato al posto dei campi di nc . Il WHERE la clausola mantiene nel set di risultati finali solo le righe che hanno NULL in nc.id; questo significa nel lc parte contengono il commento più recente di ciascun utente.

Il SELECT La clausola contiene tutti i campi di lc (quelli di nc sono tutti NULL , comunque). Il ORDER BY La clausola può essere utilizzata per ordinare il set di risultati. ORDER BY lc.id DESC mette prima i commenti più recenti e il LIMIT La clausola mantiene il set di risultati a una dimensione decente.