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 日期的主要内容,如果未能解决你的问题,请参考以下文章