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.