【问题标题】:How To find overlapping Dates in SQL Server如何在 SQL Server 中查找重叠的日期
【发布时间】:2013-08-21 09:03:54
【问题描述】:

我有一个包含 startdatetime 和 enddatetime 的表。如何找到在其他日期重叠的特定日期时间: 看下面的例子

create table #period (
    id int,
    starttime datetime,
    endtime datetime
  );

insert into #period values 
(1,'2013-10-10 08:00:00' , '2013-10-10 10:00:00'), 
(2,'2013-10-10 08:10:00' , '2013-10-10 08:20:00'), 
(3,'2013-10-10 08:10:00' , '2013-10-10 08:30:00') 
(4,'2013-10-10 08:15:00' , '2013-10-10 08:25:00') 

select * from #period


required output is '2013-10-10 08:15:00' , '2013-10-10 08:20:00' is getting overlapped in all the dates.

expected output: '2013-10-10 08:15:00' '2013-10-10 08:20:00' 5 Min

编辑:

我为之前的问题道歉 这是示例的正确详细信息

create table #period 
(
    Sitecode varchar(20),
    svrname varchar(10),
    StartTime datetime,
    downtimeEnd datetime
) 
go  

insert into #period values 
('A','S1','2013-10-10 10:00:00' , '2013-10-10 11:00:00'), 
('A','S2','2013-10-10 10:00:00' , '2013-10-10 11:00:00'),
('A','S3','2013-10-10 10:00:00' , '2013-10-10 11:00:00'), 
('A','S1','2013-10-10 03:00:00' , '2013-10-10 03:30:00'), 
('A','S2','2013-10-10 06:30:00' , '2013-10-10 07:30:00')

select * from #period

预期输出为:

Sitecode 'A' 
       Total 2.5 hours (below is the details)
       '2013-10-10 10:00:00' , '2013-10-10 11:00:00' getting overlapp - 1 hour
       '2013-10-10 03:00:00' , '2013-10-10 03:30:00' - .5 hour
       '2013-10-10 06:30:00' , '2013-10-10 07:30:00'- 1 hour

输出按sitecode 分组。并且重叠日期只考虑一次。 最终输出是必需的:

站点代码“A”= 2.5 小时

【问题讨论】:

  • 您实际上只是在询问The total number of hours that ANY server was down? 那么,如果十台服务器停机一个小时,那仍然只是一个小时的停机时间?如果只有一台服务器停机了一个小时,那仍然是一个小时的停机时间?

标签: sql-server tsql date-range


【解决方案1】:

这是在没有GROUP BY 的情况下使用HAVING 可能有意义的少数示例之一(是的,这是可能的):

SELECT MAX(starttime), MIN(endtime)
FROM #period
HAVING MIN(endtime) > MAX(starttime);

SQLFiddle DEMO

【讨论】:

    【解决方案2】:

    如果您有一组时间段并且想要所有个时间段的重叠,那么重叠将在最大开始时间和最小结束时间之间。

    select cast(starttime as date) as thedate, max(starttime), min(endtime)
    from #periods
    group by cast(starttime as date);
    

    这假设开始和结束在同一日期。第一个只是从日期时间值中提取日期(这可能因数据库而异)。这里的版本适用于 SQL Server。

    min(endtime) 小于max(starttime) 时,您没有重叠。因此,要获得重叠的日期:

    select cast(starttime as date) as thedate, max(starttime), min(endtime)
    from #periods
    group by cast(starttime as date)
    having min(endtime) > max(starttime);
    

    编辑:

    如果您想在站点代码中重叠,只需将其添加到 `group by:

    select sitecode, cast(starttime as date) as thedate, max(starttime), min(endtime)
    from #periods
    group by sitecode, cast(starttime as date)
    having min(endtime) > max(starttime);
    

    【讨论】:

    • 但是上面的 amswer 不适用于以下场景创建表 #period ( Sitecode varchar(20), svrname varchar(10), StartTime datetime, downtimeEnd datetime ) 插入 #period 值 ('A' ,'S1','2013-10-10 07:00:00','2013-10-10 07:10:00'),('B','S2','2013-10-10 08:10 :00' , '2013-10-10 08:20:00'), ('C','S3','2013-10-10 08:10:00' , '2013-10-10 08:30': 00'), ('A','S1','2013-10-10 08:15:00', '2013-10-10 08:25:00') 选择 * from #period
    • @anjali.deshetti 。 . .首先,当您希望将代码放在评论中时,请首先考虑编辑您的问题。它使它更具可读性。其次,您评论中的数据没有重叠。并且上面的查询不会返回任何东西。
    • @anjali.deshetti 如果您有其他要求和新的示例数据,请更新您的问题。
    • @GordonLinoff 我在这里疯狂的猜测是 OP 希望不同的 SiteCode 值之间有一些重叠。 (所有网站都关闭的时期)
    • 您好,很抱歉,我已经编辑了问题,希望这次很清楚。
    【解决方案3】:

    请试试这个:

    SELECT SUM(b.tm) FROM (
      SELECT datediff(second, StartTime, downtimeEnd) AS tm FROM ( 
        SELECT DISTINCT StartTime, downtimeEnd FROM #period 
      ) AS a
    ) AS b
    

    输出将是 9000 秒。比您可以将秒转换为天、小时、分钟和秒。

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-01-31
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      相关资源
      最近更新 更多