Mysql Sql查询优化-删除不在运算符中

Mysql Sql查询优化-删除不在运算符中,mysql,sql,Mysql,Sql,我将员工考勤存储在具有以下结构的表“考勤”上: EmpID, CDate 考勤系统每天插入此表,其中包含该特定日期在场的所有员工的员工id 我需要找出某个员工的缺席声明。我可以通过选择所有不在员工所在日期内的不同日期轻松做到这一点 是否有任何方法可以删除该sql语句上的not in运算符。请帮忙 以下是EmpId为01的员工的sql查询: select distinct CDate from attendance where CDate not in ( Select

我将员工考勤存储在具有以下结构的表“考勤”上:

EmpID, CDate
考勤系统每天插入此表,其中包含该特定日期在场的所有员工的员工id

我需要找出某个员工的缺席声明。我可以通过选择所有不在员工所在日期内的不同日期轻松做到这一点

是否有任何方法可以删除该sql语句上的not in运算符。请帮忙

以下是EmpId为01的员工的sql查询:

select distinct CDate 
  from attendance 
  where CDate not in (
      Select CDate from attendance where EmpID='01') 

您可以改变机制,每天为每个员工存储数据。 是的,它会添加很多行,但如何确保从记录的数据中获取所有日期?如果今天没人上班怎么办?没有人会缺席吗

如果你愿意:

EmpID, CDate, Present
1, {date}, 0|1
这样,您就可以更简单、更快地查询表大小:

select CDate from attendance where EmpID = 1 and status = 0;

问题不在NOT in子句中,而是子查询

你想要的东西更像:

SELECT DISTINCT a1.CDate, if (EmpID=NULL, false,true) as Present
FROM attendance as a1
LEFT JOIN attendance as a2 USING (CDate) 
WHERE a2.EmpID='01'
这是一个笛卡尔连接,它提取所有日期,然后连接该日期上的员工出勤状态。应该比子查询快很多


已更新,带有测试代码:

SELECT DISTINCT a1.CDate, IF (a2.EmpID IS NULL, false,true) as Present
FROM attendance AS a1
LEFT JOIN attendance AS a2 ON (a1.CDate = a2.CDate AND a2.EmpID='01') 

我对上一个答案不满意。我应该将子选择放入ON而不是聚合中。

为什么要删除NOT IN运算符?因为这需要很多时间。我想减少它。需要修改的SQL查询在哪里?MySQL 5.5和更低版本中有一个错误,当缺少索引时,in子句运行异常缓慢。您正在使用哪个版本的MySQL,每个表上都有哪些索引?它不起作用。我正在使用mySQL。它只列出员工在场的日期。请参阅更新的答案。我根据您的“规范”创建了一些数据,并对其进行了测试。它现在在每个工作日列出,但“当前”总是1。此外,此查询所用的时间与我之前的查询所用的时间几乎相同(168s vs 174s)我验证了该部件是否正常工作。至于慢度,解释建议笛卡尔使用两个简单选择,而您的使用一个依赖子查询。除了缓存之类的东西,从总体上看,我的应该更快。虽然这个答案经过一些修改后可以实现,但问题可能只是缺少索引,再加上MySQL旧版本中的一个bug,当缺少索引时会影响in子句。添加索引或升级MySQL后,此查询和原始查询都应该是快速的(