MySQL在Group by之前订购

时间:2011-02-28 10:28:35

标签: mysql wordpress group-by sql-order-by

我需要找到每个作者的最新帖子,然后对结果进行分组,这样我每个作者只会发一个最新帖子。

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

这是正确地对输出进行分组,因此我每个作者只收到一个帖子,但它是在对结果进行分组后对结果进行排序,而不是在选择之前对结果进行排序。

10 个答案:

答案 0 :(得分:22)

<德尔> 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


修改

经过一些评论后,我决定添加一些额外的信息。

我工作的公司也使用Postgres,尤其是SQL Server。此数据库不允许此类查询。所以我知道还有另一种方法可以做到这一点(我在下面写一个解决方案)。如果您没有按照投影中处理的所有列进行分组或使用聚合函数,您还必须知道您要执行的操作。否则就这样吧!

我选择了上面的解决方案,因为这是一个特定的问题。汤姆希望在wordpress网站上获得每位作者的最新帖子。在我看来,如果作者每秒做一个以上的帖子,那么分析可以忽略不计。 Wordpress甚至应该通过垃圾邮件双重检测来禁止它。我从个人经验中了解到,使用MySQL在这样一个肮脏的群体中表现有很大的好处。但如果你知道你做了什么,那么你就可以做到!我在应用程序中有这样的脏组,我在专业上负责。这里我有一些带有一些mio行的表,需要5-15s而不是100 ++秒。

对于一些优点和缺点可能有用: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

但是,如果作者每秒发布的帖子多于一个,那么您将获得多于一行而不是唯一的最后一行

现在你可以再次旋转方向盘并获得最高Id的帖子。即使在这里,至少也不能保证你真的得到了最后一个。

答案 1 :(得分:14)

不确定我是否理解您的要求是正确的,但是后面的内部声明会获取每个作者的最新post_date列表,并将这些列表与wp_posts表连接起来以获得完整的记录。

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

答案 2 :(得分:12)

我认为@edze的回答是错误的。

MySQL manual中,您可以阅读:

  

MySQL扩展了GROUP BY的使用,以便选择列表可以引用   未在GROUP BY子句中命名的非聚合列。您可以使用   此功能可通过避免不必要的列来获得更好的性能   排序和分组。但是,这主要适用于所有情况   在GROUP BY中未命名的每个非聚合列中的值是   每组相同。服务器可以自由选择每个值   组,所以除非它们相同,否则选择的值是   不定。此外,从每个组中选择值   不能通过添加ORDER BY子句来影响。排序   结果集在选择值后发生,而ORDER BY则执行   不影响服务器选择的值。

两个很棒的参考文献:

很抱歉,但由于我的声誉,我无法对@edze回复发表评论,所以我写了一个新答案。

答案 3 :(得分:6)

在ORDER BY之后执行GROUP BY,方法是使用GROUP BY包装查询:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author

答案 4 :(得分:5)

如果您在group-statement之前或之后订购,则无关紧要,因为order仅表示213转到123或321而不是更多。 group by每列只有一个条目,而不仅仅是最新的。我认为你在这里使用

的子选择
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 :(得分:4)

你怎么看待这个?似乎为我工作

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

它给我带来了最新post_date的所有作者...你在那里发现了一个问题吗?我不

答案 6 :(得分:1)

    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 

答案 7 :(得分:0)

当我们的桌子变大时,还需要检查性能。 我检查了这里问题的所有选项,PM系统有136K消息,链接表有83K行。

当您只需要计数或只需要ID时--Alex的解决方案是最好的。

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

当你需要其他字段时,我需要修改Husky110解决方案(对于我的表设计 - 这里只是示例 - 未经检查),在我的表中比子查询选项快10倍:

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

此更改可以选择多个帖子(例如,一个用户),并且可以修改为其他解决方案。

摩西。

答案 8 :(得分:0)

使用以下代码......

<?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;
    }
  }
}
?>

答案 9 :(得分:0)

这里有一个简单的答案 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

它为我创造了奇迹