在MySQL中,如何选择每行满足特定条件的数据?例如,假设我有一张表格显示员工何时到达工作岗位,它有三个字段:
CREATE TABLE ArrivalTimes (UserID INT ,Day DATE ,ArrivalTime TIME );
我想选择从未迟到的员工的所有UserID(早上9点或更早到达),这样做的最佳方法是什么?
@jjclarkson和@ davethegr8的答案很接近,但是你不能将聚合函数放在WHERE子句中.将为每一行评估WHERE子句.
您需要评估MAX()
每个组的表达式,因此您需要使用一个HAVING
子句.
试试这个:
SELECT UserID FROM ArrivalTimes GROUP BY UserID HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook评论HAVING
可能很慢.你是对的,它可能不是产生预期结果的最快捷方式.但HAVING
解决方案是最明确的.在某些情况下,性能优先级低于清晰度和可维护性.
我查看了HAVING
解决方案的EXPLAIN输出(在MySQL 5.1.30上):没有使用索引,额外的注释说" Using temporary; Using filesort
,"通常意味着性能很差.
请考虑以下查询:
SELECT DISTINCT a1.UserID FROM ArrivalTimes a1 LEFT OUTER JOIN ArrivalTimes a2 ON (a1.UserID = a2.UserID AND a2.ArrivalTime > '09:00:00') WHERE a2.UserID IS NULL;
这会生成一个使用索引的优化计划,UserID
并说:
a1:" Using index; Using temporary
"
a2:" Using where; Distinct
"
最后,以下查询生成一个优化计划,该计划似乎最有效地使用索引,并且没有临时表或文件排序.
SELECT DISTINCT a1.UserID FROM ArrivalTimes a1 WHERE NOT EXISTS (SELECT * FROM ArrivalTimes a2 WHERE a1.UserID = a2.UserID AND a2.ArrivalTime > '09:00:00');
a1:" Using where; Using index
"
a2:" Using where
"
这似乎最有可能获得最佳表现.不可否认,我的测试表中只有四行,所以这不是代表性的测试.