小编典典

MySQL order by before group by

all

本例中的任务是获取数据库中每个作者的最新帖子。

示例查询会产生不可用的结果,因为它并不总是返回的最新帖子。

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

当前接受的答案是

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

不幸的是,这个答案是简单明了的错误,并且在许多情况下产生的结果不如原始查询稳定。

我最好的解决方案是使用表单的子查询

SELECT wp_posts.* FROM 
(
    SELECT * 
    FROM wp_posts
    ORDER BY wp_posts.post_date DESC
) AS wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author

那么我的问题是一个简单的问题: 无论如何在分组之前对行进行排序而不诉诸子查询?

编辑 :这个问题是另一个问题的延续,我的具体情况略有不同。您可以(并且应该)假设还有一个 wp_posts.id 是该特定帖子的唯一标识符。


阅读 90

收藏
2022-05-04

共1个答案

小编典典

在子查询中使用 anORDER BY并不是解决此问题的最佳方法。

获得作者的最佳解决方案max(post_date)是使用子查询返回最大日期,然后在日期和最大日期将其加入到您的表中post_author

解决方案应该是:

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc

如果您有以下示例数据:

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;

子查询将返回最大日期和作者:

MaxPostDate | Author
2/1/2013    | Jim

然后,由于您将其加入表中,因此您将在这两个值上返回该帖子的完整详细信息。

请参阅SQL Fiddle with Demo

扩展我关于使用子查询准确返回此数据的评论。

MySQL 不会强制您访问列表GROUP BY中包含的每一列SELECT。因此,如果您只GROUP BY返回一列但总共返回 10
列,则不能保证返回属于该列的其他列值post_author。如果该列不在GROUP BYMySQL 中,则选择应返回的值。

使用带有聚合函数的子查询将保证每次都返回正确的作者和帖子。

附带说明一下,虽然 MySQL 允许您ORDER BY在子查询中使用 a 并允许您将 aGROUP BY应用于列表中的并非每一列,但SELECT在包括 SQL Server 在内的其他数据库中不允许此行为。

2022-05-04