仅连续 3 个月的 SQL 记录

Muj*_*man 4 sql sql-server date-arithmetic

我有 emp 表。考勤表:

emp_No Absent_Date
-------------------
111     01/03/2012
111     05/05/2012
222     13/02/2012
222     01/03/2012
222     02/03/2012
222     29/04/2012
222     09/09/2012
333     15/05/2012
333     18/09/2012
333     19/09/2012
Run Code Online (Sandbox Code Playgroud)

我需要返回如下所示的行:

emp_No Absent_Date
-------------------
222     13/02/2012
222     01/03/2012
222     02/03/2012
222     29/04/2012
Run Code Online (Sandbox Code Playgroud)

因为只有连续 3 个月缺席的 emp 没有 222。

Gor*_*off 5

您要做的是按连续月份对缺勤进行分组。让我假设您使用的是支持dense_rank()函数和基本窗口函数的合理数据库。

这个想法是按顺序找到缺席的月份。然后,计算每个员工在每个序列中的月数,并保留超过三个月的月数。

该查询通过将月份转换为月份数字来实现这一点——一年加上月份的 12 倍。然后它使用一个简单的观察。月份数减去一串数字是一个常数,对于连续的月份。通常,我row_number()用于序列。因为您在一个月内重复缺勤,所以我使用dense_rank().

select emp_no, absent_date
from (select a.*,
             max(monthnum) over (partition by emp_no, groupnum) as lastmonth,
             min(monthnum) over (partition by emp_no, groupnum) as firstmonth
      from (select a.*,
                   monthnum - dense_rank() over (partition by emp_no order by monthnum) as groupnum
            from (select a.*,
                         year(a.absent_date)*12+month(a.absent_date) as monthnum
                  from Attendance a
                 ) a
           ) a
     ) a
where lastmonth - firstmonth >= 2
Run Code Online (Sandbox Code Playgroud)

最后,因为您想要缺席日期——而不是仅仅员工编号——我使用窗口函数找到第一个月和最后一个月,并使用它们的差异作为过滤器。