sql >> Base de Datos >  >> RDS >> Mysql

mostrar el último comentario que solo 1 comentario por usuario

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.