GROUP BY 有 MAX 日期

Posted

技术标签:

【中文标题】GROUP BY 有 MAX 日期【英文标题】:GROUP BY having MAX date 【发布时间】:2013-08-15 19:56:43 【问题描述】:

执行此代码时遇到问题:

SELECT * FROM tblpm n 
WHERE date_updated=(SELECT MAX(date_updated) 
FROM tblpm GROUP BY control_number 
HAVING control_number=n.control_number)

基本上,我想返回每个控制编号的最近日期。上面的查询返回正确的输出,但需要 37 秒。在显示输出之前。

有没有其他的sql子句或命令可以比上面的查询执行得更快?

提前致谢。

【问题讨论】:

【参考方案1】:

另一种不使用group by的方式:

SELECT * FROM tblpm n 
  WHERE date_updated=(SELECT date_updated FROM tblpm n 
                        ORDER BY date_updated desc LIMIT 1)

【讨论】:

这可能行得通,但它被否决了,因为它是一种非常低效的方法。【参考方案2】:

HAVING 快速简单:

SELECT * FROM tblpm n 
FROM tblpm GROUP BY control_number 
HAVING date_updated=MAX(date_updated);

HAVING 的上下文中,MAX 查找每个组的最大值。只有每组中的最新条目才能满足date_updated=max(date_updated)。如果组内的最新消息相同,则两者都将通过HAVING 过滤器,但GROUP BY 表示只有一个出现在返回的表中。

【讨论】:

实际上我担心这不能按预期工作,我得到了一个空的查询结果集:select * from order_order_status where order_order_status.order_id = 1 group by order_order_status.order_id having order_order_status.created_at = max(order_order_status.created_at) 表有这些条目:INSERT INTO order_order_status (id, order_id, created_at) VALUES (1, 1, '2016-10-01 01:57:37'), (2, 2, '2016-10-01 01:57:54'), (3, 3, '2016-10-02 02:12:49'), (4, 3, '2016-10-02 02:14:19'), (5, 3, '2016-10-02 04:18:07'), (8, 1, '2016-10-03 01:22:53'); Having 子句中的最大值将为您提供整个表中具有最大 date_updated 的行【参考方案3】:

将子查询放在 WHERE 子句中并将其限制为 n.control_number 意味着它会多次运行子查询。这称为相关子查询,它通常是性能杀手。

最好在 FROM 子句中运行一次子查询,以获得每个控制号的最大日期。

SELECT n.* 
FROM tblpm n 
INNER JOIN (
  SELECT control_number, MAX(date_updated) AS date_updated
  FROM tblpm GROUP BY control_number
) AS max USING (control_number, date_updated);

【讨论】:

mysql 文档 -> dev.mysql.com/doc/refman/5.0/en/… 您的回答只有 8 票赞成...对于像您这样的 percona db master 来说应该很烦人 ;),多亏了您,您在一年前帮助我解决了一个愚蠢的 MySQL SP 错误,或者所以。像您这样的人使 Stack Overflow 可能成为计算机书呆子的最佳资源。 @PacketTracer,感谢您的夸奖,积分很有趣,但我更关心的是帮助人们获得好的答案并取得更大的成功。此外,到目前为止,这个问题已经被浏览了超过 9,300 次。我想我可能帮助了很多人,即使他们没有花时间投赞成票。 我在我自己的表和列中使用这个查询,但是 mysql 说:'from 子句'中的未知列'date_updated'知道为什么吗? 任何想知道USING 做什么的人,它只是将列与ON 配对的替代 - 所以在这个例子中,sn-p USING (control_number, date_updated) 等同于ON max.control_number = n.control_number AND max.date_updated = n.date_updated。在使用 Zend 等框架时,这是一个很好的知识,它使用后者格式而不是前者。【参考方案4】:

没有必要在那个子查询中分组...一个 where 子句就足够了:

SELECT * FROM tblpm n
WHERE date_updated=(SELECT MAX(date_updated)
    FROM tblpm WHERE control_number=n.control_number)

另外,您在“date_updated”列上有索引吗?这肯定会有所帮助。

【讨论】:

如果更新日期相同(并列),使用此方案时会同时显示两条记录,所以必须添加GROUP BY n. control_number 如果您需要性能,请不要使用此技术,请阅读 Bill answer

以上是关于GROUP BY 有 MAX 日期的主要内容,如果未能解决你的问题,请参考以下文章

sql 语句,在group by 中选最大值max的问题

GROUP BY TRUNC 的链(日期)

GROUP BY和HAVING 以及mysql中常用的日期函数

为啥 MAX 语句需要 Group By?

MySQL 查询优化 Group By with Max

GROUP BY 日期范围日期