在MySQL中,如何选择每行都满足特定条件的数据?例如,假设我有一个表显示员工何时到达工作地点,它具有三个字段:
CREATE TABLE ArrivalTimes
(UserID INT
,Day DATE
,ArrivalTime TIME
);
我想选择从未迟到过(上午 9 点或更早到达)的员工的所有 UserID,最好的方法是什么?
@jjclarkson 和 @davethegr8 的答案很接近,但不能将聚合函数放在 WHERE 子句中。 WHERE 子句针对每一行进行计算。
您需要评估MAX()
每个组的表达式,因此您需要使用HAVING
clause.
尝试这个:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook 评论说HAVING
可能会很慢。你是对的,这可能不是产生所需结果的绝对最快的方法。但是HAVING
解决方案是最clear。在某些情况下,性能的优先级低于清晰度和可维护性。
我查看了 EXPLAIN 输出(在 MySQL 5.1.30 上)HAVING
解决方案:没有使用索引,额外的注释说“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
"
这似乎最有可能具有最佳性能。诚然,我的测试表中只有四行,所以这不是一个具有代表性的测试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)