Su solución hace uso de un extensión de la cláusula GROUP BY que permite agrupar por algunos campos (en este caso, solo post_author
):
GROUP BY wp_posts.post_author
y seleccione columnas no agregadas:
SELECT wp_posts.*
que no se enumeran en el grupo por cláusula, o que no se utilizan en una función agregada (MIN, MAX, COUNT, etc.).
Uso correcto de la extensión a la cláusula GROUP BY
Esto es útil cuando todos los valores de las columnas no agregadas son iguales para cada fila.
Por ejemplo, suponga que tiene una mesa GardensFlowers
( name
del jardín, flower
que crece en el jardín):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
y desea extraer todas las flores que crecen en un jardín, donde crecen varias flores. Luego debe usar una subconsulta, por ejemplo, podría usar esto:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Si necesita extraer todas las flores que son las únicas flores en el jardinero, puede cambiar la condición de TENER a HAVING COUNT(DISTINCT flower)=1
, pero MySql también le permite usar esto:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
sin subconsulta, no SQL estándar, pero más simple.
Uso incorrecto de la extensión a la cláusula GROUP BY
Pero, ¿qué sucede si SELECCIONA columnas no agregadas que no son iguales para cada fila? ¿Cuál es el valor que elige MySql para esa columna?
Parece que MySql siempre elige el PRIMER valor que encuentra.
Para asegurarse de que el primer valor que encuentra es exactamente el valor que desea, debe aplicar GROUP BY
a una consulta ordenada, de ahí la necesidad de utilizar una subconsulta. No puedes hacerlo de otra manera.
Dado el supuesto de que MySql siempre elige la primera fila que encuentra, está ordenando correctamente las filas antes de GROUP BY. Pero desafortunadamente, si lee la documentación detenidamente, notará que esta suposición no es cierta.
Al seleccionar columnas no agregadas que no son siempre iguales, MySql es libre de elegir cualquier valor, por lo que el valor resultante que realmente muestra es indeterminado .
Veo que este truco para obtener el primer valor de una columna no agregada se usa mucho, y generalmente / casi siempre funciona, lo uso a veces también (bajo mi propio riesgo). Pero como no está documentado, no puede confiar en este comportamiento.
Este enlace (¡gracias ypercube!) El truco GROUP BY ha sido optimizado y muestra una situación en la que la misma consulta devuelve resultados diferentes entre MySql y MariaDB, probablemente debido a un motor de optimización diferente.
Entonces, si este truco funciona, es solo cuestión de suerte.
La respuesta aceptada en la otra pregunta me parece incorrecta:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
es una columna no agregada, y su valor será oficialmente indeterminado, pero probablemente será el primero que se post_date
encuentre. Pero dado que el truco GROUP BY se aplica a una tabla desordenada, no está seguro de cuál es el primeropost_date
encuentra.
Probablemente devolverá publicaciones que son las únicas publicaciones de un solo autor, pero incluso esto no siempre es seguro.
Una posible solución
Creo que esta podría ser una posible solución:
SELECT wp_posts.*
FROM wp_posts
WHERE id IN (
SELECT max(id)
FROM wp_posts
WHERE (post_author, post_date) = (
SELECT post_author, max(post_date)
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
) AND wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
)
En la consulta interna, estoy devolviendo la fecha máxima de publicación para cada autor. Entonces estoy teniendo en cuenta el hecho de que el mismo autor podría tener dos publicaciones al mismo tiempo, por lo que solo obtengo la ID máxima. Y luego estoy devolviendo todas las filas que tienen esas ID máximas. Podría hacerse más rápido utilizando combinaciones en lugar de la cláusula IN.
(Si está seguro de que ID
solo está aumentando, y si ID1 > ID2
también significa eso post_date1 > post_date2
, entonces la consulta podría hacerse mucho más simple, pero no estoy seguro de si este es el caso).
post_author
ypost_date
no son suficientes para obtener una fila única, por lo que tiene que haber más para obtener una fila única porpost_author