MySQL在Group by之前订购

Tom*_*Tom 50 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
Run Code Online (Sandbox Code Playgroud)

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

edz*_*dze 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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这不应该是接受的答案,因为它不能正常工作. (15认同)
  • 这不仅仅是你; 我认为这个答案没有意义.我没有得到错误,但它只给了我一行,整个集合中的最高行,而不是每个组 - 这确实有意义,因为在已经构建了行集之后处理了像ORDER一样的HAVING. (7认同)

Lie*_*ers 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
Run Code Online (Sandbox Code Playgroud)


aan*_*ton 12

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

MySQL手册中,您可以阅读:

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列.您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能.但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用.服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的.此外,添加ORDER BY子句不会影响每个组中值的选择.选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值.

两个很好的参考:

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


111*_*01b 7

通过使用GROUP BY包装查询,在ORDER BY之后执行GROUP BY:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author
Run Code Online (Sandbox Code Playgroud)


Hus*_*110 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 = ... )
Run Code Online (Sandbox Code Playgroud)