当涉及到SQL和DB时,我不是太多的熟练
我有一张桌子,其中所有员工的缺席是由病假造成的,该叶子由代表" date_from',date_to"one_answers" date_to"的列和缺席的"持续时间"造成。我需要选择连续30天病假的每名员工。我在这里发现的问题是,一个人可以在DB中提交多个病假文件。这意味着一个人可以连续30天休病假,但是在检查特定的"员工_id"的多个记录时,该信息应得到确认。
以示例说明:
Employee_id | Name | Date_from | Date_to | Duration
------------+-------------+-------------+-------------+----------
00001 | John Newbie | 01-Apr-2018 | 25-Apr-2018 | 25 days
00001 | John Newbie | 26-Apr-2018 | 03-May-2018 | 8 days
在此示例中,Asbecne将总结长达33天,该员工应通过查询退还,而如果这2个记录之间至少有一天的差距(例如,员工在工作中出席4月26日,从4月27日开始(,该员工不应在报告中。
我不知道如何开始。感谢任何帮助。
谢谢
这称为"间隙和岛"问题。通过开始和结束日期使它变得更加复杂。
这个想法是确定岛屿从哪里开始。您可以通过开始没有重叠的开始,然后使用累积总和来识别这些组来做到这一点。其余的只是聚集:
select employee_id, min(date_from) as date_from, max(date_to) as date_to
from (select a.*, sum(flag_start) as grp
from (select a.*,
(case when exists (select 1
from absences a2
where a2.employee_id = a.employee_id and
a2.date_from <= a.date_to and
a2.date_to >= a.date_from
)
then 0 else 1
end) as flag_start
from absences a
) a
) a
group by employee_id, grp
having max(date_to) >= date_add(day, 30, min(date_from));
Lag
功能在SQL Server 2012中可用,在这种情况下非常有用
select
Employee_id, Name, Date_from = min(Date_from), Date_to = max(Date_to), Duration = sum(Duration)
from (
select
Employee_id, Name, Date_from, Date_to, Duration
, grp = sum(iif(datediff(dd, previous, Date_from) = 1, 0, 1)) over (partition by Employee_id order by Date_from)
from (
select
*, previous = lag(Date_to) over (partition by Employee_id order by Date_from)
from myTable
) t
) t
group by Employee_id, Name, grp
having sum(Duration) >= 30