MySQL Orden antes de Grupo por


Necesito encontrar la publicación más reciente para cada autor y luego agrupar los resultados para 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 es agrupar correctamente la salida, por lo que solo obtengo un post por autor, pero está ordenando los resultados después de que se hayan agrupado y no antes de que se hayan seleccionado.

Author: edze, 2011-02-28

10 answers

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 añadir algunas informaciones adicionales.

La compañía en la que estoy trabajando también usa Postgres y especialmente SQL Server. Estas bases de datos no permiten este tipo de consultas. Así que sé que hay otra manera de hacer esto (escribo una solución a continuación). También debe saber lo que hace si no agrupa por todas las columnas tratadas en la proyección o utiliza funciones agregadas. ¡Si no, déjalo!

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 un post por segundo. Wordpress incluso debería prohibirlo por su detección de spam-doble-post. Sé por experiencia personal que hay un beneficio realmente significativo en el rendimiento haciendo un grupo tan sucio con MySQL. Pero si sabes lo que ¡hazlo, entonces puedes hacerlo! Tengo grupos tan sucios en aplicaciones de las que soy responsable profesionalmente. Aquí tengo tablas con algunas filas mio que necesitan 5-15s 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 aquí hay más de un post por segundo para un autor obtendrá más de una fila y no la única última.

Ahora usted puede girar la rueda de nuevo y obtener el poste con el más alto Id. Incluso aquí, al menos no se garantiza que realmente obtenga el último.

 22
Author: edze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-09 13:54:04

No estoy seguro de si entiendo su requisito correcto, pero la siguiente declaración interna obtiene la lista de la última post_date para cada autor y las une con 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
 14
Author: Lieven Keersmaekers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 06:03:53

Creo que la respuesta de @edze es incorrecta.

En el Manual de MySQL se puede leer:

MySQL extiende el uso de GROUP BY para que la lista select pueda referirse a columnas no agregadas no nombradas en la cláusula GROUP BY. Usted puede utilizar esta característica para obtener un mejor rendimiento al evitar la columna innecesaria ordenar y agrupar. Sin embargo, esto es útil principalmente cuando todos los valores en cada columna no agregada no nombrada en el GRUPO POR son mismo para cada grupo. El servidor es libre de elegir cualquier valor de cada uno grupo, así que a menos que sean los mismos, los valores elegidos son indeterminado. Además, la selección de valores de cada grupo no se puede influir añadiendo una cláusula ORDER BY. Clasificación de la el conjunto de resultados se produce después de que se hayan elegido los valores y se ORDENE POR does no afecta a qué valores elige el servidor.

Dos grandes referencias:

Lo siento, pero no puedo comentar la respuesta @edze debido a mi reputación, así que he escrito una nueva respuesta.

 12
Author: aanton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-02 06:44:42

Haga un GRUPO POR después del ORDEN POR envolviendo su consulta con el GRUPO DE la siguiente manera:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author
 6
Author: 11101101b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-30 19:58:07

No importa si ordena antes o después de la instrucción group, porque order significa solo que 213 va a 123 o 321 y no más. agrupar por solo toma algunas entradas por columna, no solo las más recientes. Considero que el trabajo con subselecciones 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 = ... )
 5
Author: Husky110,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-28 10:34:18

¿Qué piensas de esto?? Parece que funciona para mí

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 post_date más actualizada ... ¿Identificas algún problema ahí?? Yo no

 4
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-05 20:07:22
    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 
 1
Author: Mhd Jazaery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-24 19:08:52

Cuando nuestra tabla se hizo grande, el rendimiento debe comprobarse también. He comprobado todas las opciones en las preguntas aquí, con un sistema de PM con un mensaje de 136K y una tabla de enlaces con filas de 83K.

Cuando solo necesita contar, o solo IDs, 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 (a mi diseño de tabla-aquí es solo un ejemplo-no marcado), 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 un post (uno para el usuario, por ejemplo), y se puede modificar a otras soluciones.

Moshe.

 0
Author: Moshe L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 08:32:19

Utilice 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;
    }
  }
}
?>
 0
Author: Kausha Mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-25 11:29:53

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

Hizo maravillas para mí

 0
Author: Black Bronco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-27 14:37:47