trucos - Orden MySQL antes de agrupar por
trucos mysql (10)
Necesito encontrar la publicación más reciente para cada autor y luego agrupar los resultados, de modo que solo una publicación más reciente para cada autor.
SELECT wp_posts.* FROM wp_posts
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
GROUP BY wp_posts.post_author
ORDER BY wp_posts.post_date DESC
Esto agrupa correctamente el resultado, por lo que solo obtengo una publicación por autor, pero ordena los resultados una vez que se han agrupado y no antes de que se hayan seleccionado.
¿¿Qué piensas sobre esto?? Parece funcionar para mi
SELECT wp_posts.post_author, MAX(wp_posts.post_date), wp_posts.status, wp_posts.post_type
FROM wp_posts
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
GROUP BY wp_posts.post_author
Me trae todos los Autores con la fecha_publicada más actualizada ... ¿Identifica un problema allí? Yo no
AQUÍ una respuesta simple de http://www.cafewebmaster.com/mysql-order-sort-group
SELECT * FROM
(
select * from `my_table` order by timestamp desc
) as my_table_tmp
GROUP BY catid
ORDER BY nid desc
funcionó de maravillas para mí
Creo que la respuesta de @edze es incorrecta.
En el manual de MySQL puedes leer:
MySQL amplía el uso de GROUP BY para que la lista de selección pueda hacer referencia a columnas no agregadas no nombradas en la cláusula GROUP BY. Puede usar esta función para obtener un mejor rendimiento al evitar la clasificación y clasificación de columnas innecesarias. Sin embargo, esto es útil principalmente cuando todos los valores en cada columna no agregada no nombrada en GROUP BY son los mismos para cada grupo. El servidor puede elegir libremente cualquier valor de cada grupo, de modo que, a menos que sean iguales, los valores elegidos son indeterminados. Además, la selección de valores de cada grupo no puede verse influenciada por la adición de una cláusula ORDER BY. La clasificación del conjunto de resultados se produce después de que se hayan elegido los valores, y ORDER BY no afecta a los valores que elige el servidor.
Dos grandes referencias:
- http://kristiannielsen.livejournal.com/6745.html
- http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
Lo siento, pero no puedo comentar la respuesta @edze debido a mi reputación, así que escribí una nueva respuesta.
Cuando nuestra mesa se hizo grande, el rendimiento también debe verificarse. Revisé todas las opciones en las preguntas aquí, con un sistema de PM con un mensaje de 136K y una tabla de enlaces con 83K filas.
Cuando solo necesita contar, o solo ID: la solución de Alex es la mejor.
SELECT wp_posts.post_author, MAX(wp_posts.post_date), wp_posts.status, wp_posts.post_type
FROM wp_posts
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
GROUP BY wp_posts.post_author
Cuando necesite otros campos, necesito modificar la solución Husky110 (para el diseño de mi mesa, aquí solo es un ejemplo, no está marcada), que en mis tablas 10 veces más rápido que la opción de subconsulta:
SELECT wp_posts.* FROM wp_posts,
(Select post_id as pid, max(post_date) maxdate from wp_posts where author = ... group by author order by maxdate desc limit 4) t
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
AND wp_posts.post_id = pid
Este cambio puede seleccionar más de una publicación (una para el usuario, por ejemplo) y puede modificarse para otras soluciones.
Moshe.
Haz un GROUP BY después de ORDER BY al envolver tu consulta con el GROUP BY así:
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author
No estoy seguro si entiendo su requerimiento correcto, pero al seguir el enunciado interno obtengo la lista de la última fecha_posicion para cada autor y los reincorpo a la tabla wp_posts para obtener un registro completo.
SELECT *
FROM wp_posts wp
INNER JOIN (
SELECT post_author
, MAX(post_date) AS post_date
FROM wp_posts
WHERE post_status = ''publish''
AND post_type = ''post''
GROUP BY
post.author
) wpmax ON wpmax.post_author = wp.post_author
AND wpmax.post_date = wp.post_date
ORDER BY
wp.post_date DESC
Usa el siguiente código ...
<?php
//get all users, iterate through users, query for one post for the user,
//if there is a post then display the post title, author, content info
$blogusers = get_users_of_blog();
if ($blogusers) {
foreach ($blogusers as $bloguser) {
$args = array(
''author'' => $bloguser->user_id,
''showposts'' => 1,
''caller_get_posts'' => 1
);
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
// $user = get_userdata($bloguser->user_id);
// echo ''This is one post for author with User ID: '' . $user->ID . '' '' . $user- >user_firstname . '' '' . $user->user_lastname;
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <? php the_title_attribute(); ?>"><?php the_title(); ?></a>
<small><?php the_time(''F jS, Y'') ?> by <?php the_author_posts_link() ?> </small><?php
the_content();
endwhile;
}
}
}
?>
no importa si ordena antes o después de la declaración de grupo, porque el orden significa solo que 213 pasa a 123 o 321 y no más. group by toma solo ALGUNA entrada por columna, no solo la última. Te considero trabajando con subselects aquí como
SELECT wp_posts.* FROM wp_posts
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
AND wp_posts.post_date = (Select max(post_date) from wp_posts where author = ... )
select wp_posts.* from wp_posts
where wp_posts.post_status=''publish''and wp_posts.post_type=''post''
group by wp_posts.post_author
having wp_posts.post_date = MAX(wp_posts.post_date) /* ONLY THE LAST POST FOR EACH AUTHOR */
order by wp_posts.post_date desc
EDITAR:
Después de algunos comentarios, he decidido agregar información adicional.
La compañía en la que estoy trabajando también usa Postgres y especialmente SQL Server. Estas bases de datos no permiten tales consultas. Entonces sé que hay otra forma de hacerlo (escribo una solución a continuación). También debe saber qué hacer si no agrupa por todas las columnas tratadas en la proyección o usa funciones agregadas. De lo contrario, déjalo estar!
Elegí la solución anterior, porque es una pregunta específica. Tom quiere obtener la publicación reciente de cada autor en un sitio de wordpress. En mi opinión, es insignificante para el análisis si un autor hace más de una publicación por segundo. Wordpress incluso debería prohibirlo mediante su detección de doble correo no deseado. Sé por experiencia personal que hay un beneficio realmente significativo en el desempeño haciendo un grupo tan sucio con MySQL. Pero si sabes lo que haces, ¡entonces puedes hacerlo! Tengo grupos tan sucios en aplicaciones de las que soy profesionalmente responsable. Aquí tengo tablas con algunas filas de mio que necesitan 5-15 en lugar de 100 ++ segundos.
Puede ser útil sobre algunos pros y contras: http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/debunking-group-by-myths.html
SELECT
wp_posts.*
FROM
wp_posts
JOIN
(
SELECT
g.post_author
MAX(g.post_date) AS post_date
FROM wp_posts as g
WHERE
g.post_status=''publish''
AND g.post_type=''post''
GROUP BY g.post_author
) as t
ON wp_posts.post_author = t.post_author AND wp_posts.post_date = t.post_date
ORDER BY wp_posts.post_date
Pero si hay más de una publicación por segundo para un autor, obtendrá más de una fila y no la última .
Ahora puede girar la rueda nuevamente y obtener la publicación con la Id
más alta. Incluso aquí, al menos, no está garantizado que realmente consigas el último.
SELECT wp_posts.*,max(wp_posts.post_date) FROM wp_posts
WHERE wp_posts.post_status=''publish''
AND wp_posts.post_type=''post''
GROUP BY wp_posts.post_author