在MySQL中选择所有行满足条件

Ben*_*ino 6 mysql select

在MySQL中,如何选择每行满足特定条件的数据?例如,假设我有一张表格显示员工何时到达工作岗位,它有三个字段:

CREATE TABLE ArrivalTimes
(UserID INT
,Day DATE 
,ArrivalTime TIME
);
Run Code Online (Sandbox Code Playgroud)

我想选择从未迟到的员工的所有UserID(早上9点或更早到达),这样做的最佳方法是什么?

Bil*_*win 18

@jjclarkson和@ davethegr8的答案很接近,但是你不能将聚合函数放在WHERE子句中.将为每一行评估WHERE子句.

您需要评估MAX()每个组的表达式,因此您需要使用一个HAVING子句.

试试这个:

SELECT UserID 
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
Run Code Online (Sandbox Code Playgroud)

@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;
Run Code Online (Sandbox Code Playgroud)

这会生成一个使用索引的优化计划,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'); 
Run Code Online (Sandbox Code Playgroud)
  • a1:" Using where; Using index"
  • a2:" Using where"

这似乎最有可能获得最佳表现.不可否认,我的测试表中只有四行,所以这不是代表性的测试.