对于SQL和DB而言,我并不是太擅长,但我正在努力解决相当严重的问题(与我的知识相比):
我有一张表,其中包含了所有员工的所有缺席情况,这些表是由病假的叶子引起的,其中列表示'date_from',date_to'和缺席的'持续时间'。我需要选择每个病假的员工至少连续30天。我在这里发现问题的一点是,一个人可以提交在DB中注册的多个病假文件。这意味着一个人可以连续30天休病假,但是当检查多个具有特定“employee_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天,这个员工应该通过查询返回,而这两个记录之间至少有一天差距(例如,员工出现在工作中4月26日,4月27日缺席),该员工不应出现在报告中。
我不知道如何开始。我感谢任何帮助。
谢谢
答案 0 :(得分:3)
这被称为“差距和岛屿”问题。通过开始和结束日期使它变得有点复杂。
想法是确定岛屿的起点。您可以通过开始没有重叠然后使用累积总和来识别组来完成此操作。其余的只是聚合:
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));
答案 1 :(得分:0)
Lag
函数非常有用
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