Por qué no funciona con GROUP BY
SELECT *
no se puede usar con GROUP BY
; es un SQL no válido. GROUP BY
no selecciona las filas de la tabla. Crea grupos de filas utilizando las expresiones proporcionadas y luego, a partir de cada grupo, genera un nuevo registro y calcula cada columna de este nuevo registro utilizando los valores involucrados en la expresión.
Las columnas que aparecen en el SELECT
cláusula debe cumplir una de las siguientes reglas:
- también aparecen en el
GROUP BY
cláusula; - se usan con
GROUP BY
funciones agregadas ; - son funcionalmente dependientes de las columnas que aparecen en el
GROUP BY
cláusula.
Mientras *
es un atajo para todos los nombres de columna de la(s) tabla(s) usada(s) por la consulta, para su consulta solo el user
columna satisface uno de los requisitos anteriores.
Antes de la versión 5.7.5
MySQL no implementó la tercera regla anterior. Solía aceptar consultas que contienen en el SELECT
columnas de la cláusula que no siguen a ninguna de las GROUP BY
requisitos El valor devuelto por la consulta para tales columnas fue indeterminado
.
Desde la versión 5.7.5, MySQL rechaza el GROUP BY
consultas que cumplen los requisitos.
La solución
De cualquier manera, la solución para su problema no implica GROUP BY
. Se puede lograr fácilmente usando un LEFT JOIN
con las condiciones correctas:
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
Cómo funciona
Se une a la tabla comments
, alias lc
("lc" del "último comentario" de un usuario) contra sí mismo, con el alias nc
("nc" de "comentario más reciente"). La cláusula de unión coincide con cada entrada de lc
con todas las entradas de nc
que pertenecen al mismo usuario (lc.user = nc.user
) y son más recientes (lc.id < nc.id
; Asumí que las ID se asignan secuencialmente y los comentarios más nuevos tienen valores más grandes para id
).
El uso de LEFT JOIN
asegura que cada fila de lc
aparece en el resultado de la unión, incluso cuando no se encuentra ninguna fila coincidente en nc
(porque no hay un comentario más nuevo del mismo usuario). En este caso, NULL
se usa en lugar de los campos de nc
. El WHERE
la cláusula mantiene en el conjunto de resultados final solo las filas que tienen NULL
en nc.id
; esto significa en el lc
parte contienen el comentario más reciente de cada usuario.
El SELECT
cláusula contiene todos los campos de lc
(los de nc
son todos NULL
, de todos modos). El ORDER BY
La cláusula se puede utilizar para ordenar el conjunto de resultados. ORDER BY lc.id DESC
pone los comentarios más recientes primero y el LIMIT
mantiene el conjunto de resultados en un tamaño decente.