SQL分组结果没有重叠的日期

时间:2018-08-16 12:34:13

标签: sql sql-server

我有大量的员工数据,其中包含许多与开始和结束日期相关的键。我想将这些分组在一起,形成一个在开始日期和结束日期之间没有重复的唯一条目。例如,我希望输出如下所示。

EmpID   Name    Status  Team    Start   End
1   Zoe Employed    Team01  2018-01-01  2018-01-04
1   Zoe CareerBreak Team01  2018-01-05  2018-01-07
1   Zoe Employed    Team01  2018-01-08  2018-01-10
2   Bob Employed    Team01  2018-01-01  2018-01-03
2   Bob Employed    Team02  2018-01-04  2018-01-10

我可以通过以下其中一种形式轻松获取数据。

EmpID   Name    Status  Start   End
1   Zoe Employed    2018-01-01  2018-01-04
1   Zoe CareerBreak 2018-01-05  2018-01-07
1   Zoe Employed    2018-01-08  2018-01-10
1   Zoe Team01  2018-01-01  2018-01-10
2   Bob Employed    2018-01-01  2018-01-10
2   Bob Team01  2018-01-01  2018-01-03
2   Bob Team02  2018-01-04  2018-01-10

EmpID   Name    Status  Team    Date
1   Zoe Employed    Team01  2018-01-01
1   Zoe Employed    Team01  2018-01-02
1   Zoe Employed    Team01  2018-01-03
1   Zoe Employed    Team01  2018-01-04
1   Zoe CareerBreak Team01  2018-01-05
1   Zoe CareerBreak Team01  2018-01-06
1   Zoe CareerBreak Team01  2018-01-07
1   Zoe Employed    Team01  2018-01-08
1   Zoe Employed    Team01  2018-01-09
1   Zoe Employed    Team01  2018-01-10
2   Bob Employed    Team01  2018-01-01
2   Bob Employed    Team01  2018-01-02
2   Bob Employed    Team01  2018-01-03
2   Bob Employed    Team02  2018-01-04
2   Bob Employed    Team02  2018-01-05
2   Bob Employed    Team02  2018-01-06
2   Bob Employed    Team02  2018-01-07
2   Bob Employed    Team02  2018-01-08
2   Bob Employed    Team02  2018-01-09
2   Bob Employed    Team02  2018-01-10

通过遍历每个日期记录并进行比较,我已经能够做到这一点。但这显然需要太长时间。

我在分组时遇到的问题是更改前后的细节相同。因此,从分组中排除日期以采用最小和最大日期将为我提供以下信息。

EmpID   Name    Status  Team    Start   End
1   Zoe Employed    Team01  2018-01-01  2018-01-10
1   Zoe CareerBreak Team01  2018-01-05  2018-01-07

这应该是3个条目。我不认为还有其他方法可以做到,我很确定分组不是为此的选项,但它可能是一个起点。我很乐意自己进行研究,但是我很固执,需要暗示要看什么,这可能提供一种解决方案,可以将其拆分为不重叠的日期。 (显然,这是一个非常简化的数据块,但希望足以说明问题)

1 个答案:

答案 0 :(得分:1)

这是一个“群岛”问题。您可以通过从日期中减去数字序列来解决问题-对于连续的日期来说,这是常数。这将使用您的数据的长格式:

select empid, name, status, team, min(date), max(date)
from (select t.*,
             row_number() over (partition by empid, status, team order by date) as seqnum
      from t
     ) t
group by empid, name, status, team, dateadd(day, -seqnum, date)
order by empid, min(date);