【问题标题】:Determine time gaps in SQL确定 SQL 中的时间间隔
【发布时间】:2020-09-27 04:46:30
【问题描述】:

我正在尝试自学滞后和领先功能,并认为我会尝试使用以下报告,但我运气不佳。我的目标是为一个部门记录一些随叫随到的开始和停止时间,并创建一份报告,详细说明没有覆盖的那一天的时间间隔。假设该部门每周 7 天、每天 24 小时提供服务。处理此问题的唯一方法是将其加入具有可用日期和每一分钟的日期时间表吗?任何建议将不胜感激。

以下数据的预期结果是:

on 09/01/2020 dept 3042300031 had a time gap from 20:59 to 21:00 and a time gap from 22:59 to 23:59
on 09/02/2020 dept 3042300031 had a time gap from 00:00 to 00:05 and a time gap from 20:59 to 22:00 and a time gap from 22:50 to 23:59
on 09/03/2020 dept 3042300031 had a time gap from 00:00 to 23:59
on 09/04/2020 dept 3042300031 had a time gap from 20:59 to 23:59
IF OBJECT_ID('tempdb..#report') IS NOT NULL DROP TABLE #report
GO

CREATE TABLE #report (
 Contact_Date date
,Line   int
,Start_Instant_dttm smalldatetime
,End_Instant_dttm datetime
,Asgn_to_Role   int
,Asgn_to_Team   bigint
);

INSERT INTO #report
SELECT
'9/1/2020',1,'9/1/2020 00:00','9/1/2020 20:59',270,3042300031
UNION
SELECT
'9/1/2020',2,'9/1/2020 21:00','9/1/2020 22:59',270,3042300031
UNION
SELECT
'9/2/2020',1,'9/2/2020 00:05','9/2/2020 20:59',270,3042300031
UNION
SELECT
'9/2/2020',2,'9/2/2020 22:00','9/2/2020 22:59',270,3042300031
UNION
SELECT
'9/4/2020',1,'9/4/2020 00:00','9/4/2020 20:59',270,3042300031;

【问题讨论】:

  • 请添加预期结果应该是什么样子以及 24:00 是什么时候?
  • 到目前为止你有什么尝试?
  • 是的,2400 上的大脑放屁将其更改为 2359。就我到目前为止所尝试的而言。我尝试了类似于 dnoeth 的第一个 cte 的方法,我得到了 on call 之间的时间间隔,但在日历天数方面遇到了问题;因此我提到了加入日期时间表。哪个 dnoeth 似乎只加入了一个日期表。

标签: sql sql-server-2012


【解决方案1】:

找出差距很简单:

with cte as
 ( 
   select Asgn_to_Team, Start_Instant_dttm, End_Instant_dttm
      ,lag(End_Instant_dttm) 
       over (partition by Asgn_to_Team
             order by Start_Instant_dttm) as prev_end
   from #report
 )
select Asgn_to_Team, prev_end as gap_start, Start_Instant_dttm as gap_end
from cte
where prev_end < Start_Instant_dttm

但是将它们分成天要困难得多,您需要加入日历表:

with cte as
 ( 
   select Asgn_to_Team, Start_Instant_dttm, End_Instant_dttm
      ,lag(End_Instant_dttm) 
       over (partition by Asgn_to_Team
             order by Start_Instant_dttm) as prev_end
   from #report
 )
select Asgn_to_Team, 
   case when prev_end > cast(cal.cal_date as datetime)
        then prev_end
        else cast(cal.cal_date as datetime)
   end as gap_start,
   case when Start_Instant_dttm < cast(dateadd(day, 1, cal.cal_date) as datetime)
        then Start_Instant_dttm
        else cast(dateadd(day, 1, cal.cal_date) as datetime)
   end as gap_end
from cte join cal -- one row for each date covered
  on cast(cal.cal_date as datetime) <= Start_Instant_dttm
 and cast(dateadd(day, 1, cal.cal_date) as datetime) > prev_end
where prev_end < Start_Instant_dttm

希望我得到了 >/fiddle

【讨论】:

  • 感谢 cte 是我所在的位置,但我试图将它加入到按时间(按分钟)和日期破坏的表中,但无法正常工作。我将创建一个日历表,看看你的工作原理。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 2023-02-21
  • 1970-01-01
  • 2011-05-08
  • 2016-03-18
相关资源
最近更新 更多