在 SQL 中计算连续班次和天数

Posted

技术标签:

【中文标题】在 SQL 中计算连续班次和天数【英文标题】:Counting consecutive shift and days in SQL 【发布时间】:2016-11-23 01:24:16 【问题描述】:

我正在尝试显示团队工作的连续班次和天数。我尝试了许多解决方案,但都无法完全正确。

数据是日期、班次、船员。有一个昼夜班和3个工作人员。 ConsecutiveShift 和 ConsecutiveDay 是我正在尝试制作的字段。输出将用于根据连续班次/工作天数来查看生产力。

非常感谢任何帮助

Dateop               Shift  Crew
2015-12-23 00:00:00  D      B Crew
2015-12-23 00:00:00  N      A Crew
2015-12-24 00:00:00  D      B Crew
2015-12-24 00:00:00  N      A Crew
2015-12-25 00:00:00  D      C Crew
2015-12-25 00:00:00  N      B Crew
2015-12-26 00:00:00  D      C Crew
2015-12-26 00:00:00  N      B Crew
2015-12-27 00:00:00  D      C Crew
2015-12-27 00:00:00  N      B Crew
2015-12-28 00:00:00  D      C Crew
2015-12-28 00:00:00  N      B Crew
2015-12-29 00:00:00  D      C Crew
2015-12-29 00:00:00  N      B Crew
2015-12-30 00:00:00  D      A Crew
2015-12-30 00:00:00  N      C Crew
2015-12-31 00:00:00  D      A Crew
2015-12-31 00:00:00  N      C Crew
2016-01-01 00:00:00  D      A Crew
2016-01-01 00:00:00  N      C Crew
2016-01-02 00:00:00  D      A Crew
2016-01-02 00:00:00  N      C Crew

所需输出 - 前 3 列是原始数据,第 4 列和第 5 列是我要生成的计数

【问题讨论】:

什么是 DBMS(Sql Server、Oracle、mysql 等)? 我不明白你需要的输出。你能进一步解释一下吗?为什么连续重置为5?这是硬限制还是基于某种工作日窗口?为什么 30th = 1,6 而不是 1,1? 您能否将输入数据粘贴为文本而不是图片。让其他人更容易帮助您。 数据库是 SQL Server 2012。尼克,抱歉解释不佳(我知道我想要什么,哈哈)。有 3 个船员 - A、B 和 C 船员。运营 24/7,每个工作人员轮班工作 12 小时,5 天,5 夜,5 天休息。轮班计数器将在每个工作人员工作 5 天和 5 晚后重置,但天数将持续到 10 天,然后在他们休息时重置。我要进行的分析是基于他们工作的天数,也许在他们的第三和第四夜班工作人员的工作效率较低等。 【参考方案1】:

下面的查询应该可以工作,使用窗口函数:

With cte As (
    Select DateOp, Shift, Crew,
        DateDiff(Day, DateOp, '2016-01-01') + Row_Number() Over (Partition By Crew, Shift Order By DateOp) As ShiftIsland,
        DateDiff(Day, DateOp, '2016-01-01') + Row_Number() Over (Partition By Crew Order By DateOp) As DayIsland
      From [YourTable])      
Select DateOp, Shift, Crew,
    Row_Number() Over (Partition By Crew, Shift, ShiftIsland Order By DateOp) As ConsecutiveShifts,
    Row_Number() Over (Partition By Crew, DayIsland Order By DateOp) As ConsecutiveDays
  From cte
  Order By Crew, DateOp, Shift;

【讨论】:

门多西,你就是男人!!完美运行,我只是无法完全正确地理解逻辑。【参考方案2】:

我认为这是一个基本的row_number()。对于您提供的数据:

select t.*,
       row_number() over (partition by shift, crew order by date) as consecutiveshift,
       row_number() over (partition by crew order by date) as consecutiveday
from t;

这至少会返回您在问题中拥有的数据。

【讨论】:

此解决方案不适用于在 12 月 24 日至 12 月 30 日之间休息的机组 A。这应在 12 月 30 日将其ConsecutiveDay 重置为 1,但您的查询会继续增加它。 @mendosi 。 . .正如答案中明确所述,这将返回问题中提供的结果。 OP 没有说明“缺失”天数会发生什么,或者即使数据中可能发生这种情况。 实际上,OP 确实在您回答之前发布的评论中指定了。 “轮班计数器将在每个工作人员工作 5 天,然后 5 晚后重置,但白天将持续到 10 天然后在他们休息时重置。”最初的问题也很清楚在几个地方说连续几天。

以上是关于在 SQL 中计算连续班次和天数的主要内容,如果未能解决你的问题,请参考以下文章

SQL 计算连续天数

SQL 计算最长连续登录天数

sql 连续活跃天数

Hive计算最大连续登陆天数

spark sql 连续登录最大天数

SQL经典问题 找出连续日期及连续的天数