【问题标题】:How to find missing data in a range of dates in oracle sql如何在oracle sql中查找一系列日期中的缺失数据
【发布时间】:2016-11-17 01:33:25
【问题描述】:

我有一个表 (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') )

这会起作用,但它不会告诉我员工缺勤的日期

【问题讨论】:

  • 在您的输出中,您是否需要区分“工作日”或“工作日”,以及“周末或节假日”?我假设在周日(在美国),所有员工都会“缺席”。

标签: sql oracle


【解决方案1】:

选择不同的empno 从 EMPLOYEES e, left join ATTENDANCE a 在 e.empno = a.empno 和 e.date=a.date 其中 a.empno 为 NULL

【讨论】:

  • EMPLOYEES 表中没有日期
【解决方案2】:

我想要一个查询来检索员工编号和日期 缺席

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

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

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

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

然后使用外连接和 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 EMPLOYEES e 
LEFT JOIN ATTENDANCE a 
ON ( a.empno = e.empno AND a."DATE" = d."DATE" )
WHERE a."DATE" IS NULL
order by 1,2

【讨论】:

    【解决方案3】:

    这里更简洁的方法是使用 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2022-10-05
      相关资源
      最近更新 更多