如何在oracle sql中查找日期范围内的缺失数据

时间:2016-07-14 08:20:43

标签: sql oracle

我有桌子(ATTENDANCE)包含员工的出勤情况如下

EMPNO   DATE
2     07/11/2016
2     07/12/2016
3     07/12/2016
6     07/13/2016
7     07/13/2016

包含员工编号(empno)和参加日期(日期)

另一张表(EMPLOYEES)包含公司的所有雇员,例如这样

EMPNO   NAME
1       Musa
2       Ali 
3       Khalid
6       James
7       Sara

我可以通过使用此代码找到某个员工是否在特定日期缺席

select empno 
from EMPLOYEES 
where empno not in (select empno 
               from ATTENDANCE
               where date = '07/11/2016')

我希望在特定范围之间的任何一天检索缺席员工的清单 我试图使用这个查询

select empno 
from EMPLOYEES 
where empno not in (select empno 
               from ATTENDANCE
               where  date between '07/11/2016' and  '07/13/2016'  )

但这会给我那些在所有这个范围内缺席的人如果一名员工在一天内缺席,那么它将无法撤销

我想要一个查询来检索empno和员工缺席的日期?

更新 我也试过这个,因为 sagi 提到了

select empno 
from EMPLOYEES 
where empno not in (select empno
    from ATTENDANCE
    group by empno
    having count(empno) = to_date(' 07/09/2016','mm,dd,rrrr') - to_date('07/13/2016','mm,dd,rrrr') )

这会有效但不会在员工缺席的日期给我

3 个答案:

答案 0 :(得分:2)

  

我想要一个查询来检索员工所在的 empno和日期   缺席

在这种情况下,您需要使用例如此查询生成给定范围内的所有可能日期:

var total = array[1].toString() + 1; // result 101

然后使用交叉连接生成所有可能的对:date + employe

SELECT date '2016-07-11' + level - 1 As "DATE" from dual
CONNECT BY LEVEL <= date '2016-07-13' - date '2016-07-11' + 1;

DATE            
-----------------
16/07/11 00:00:00
16/07/12 00:00:00
16/07/13 00:00:00

然后使用外连接和IS NULL条件过滤现有记录(只留下不存在的对:empno + date)

SELECT e.empno, d."DATE"
FROM (
    SELECT date '2016-07-11' + level - 1 As "DATE" from dual
    CONNECT BY LEVEL <= date '2016-07-13' - date '2016-07-11' + 1
) d
CROSS JOIN empno e

答案 1 :(得分:0)

选择distinct empno 来自EMPLOYEES e,离开加入ATTENDANCE a 在e.empno = a.empno和e.date = a.date 其中a.empno为NULL

答案 2 :(得分:0)

一种更清洁的方法是使用CTE识别出勤表中的所有不同日期。

然后我们与员工进行交叉联接表以获取所有可能的组合

最后,我们将在“出勤”表中检查EmpNo和Date元组的存在。

With Dates (date)  as (Select Distinct Date from Attendance )

Select Emp.EmpNo, dates.date from employee emp cross join Dates
where (emp.empno, dates.date) not in
(Select Empno, date from Attendance