代码之家  ›  专栏  ›  技术社区  ›  Axarydax

选择与SQL重叠的日期时间事件

  •  0
  • Axarydax  · 技术社区  · 14 年前

    Events (ID int, Event int, StartTime datetime, Duration int ).

    Event

    Duration 事件处于活动状态的秒数。

    事件1 是活动的,但是减去 事件2

    E、 g.事件1从1:00到6:00,事件2从0:00到2:00,事件2从5:00到6:00。总时间应为2:00到5:00->3小时。

    我可以想到一个办法:为每一个人 全部查找 事件2 它可以与事件1相交,并且对于每个事件 在该集合中:修剪其持续时间以仅获取事件1期间处于活动状态的部分。

    e、 g.对于我的事件1(1:00-6:00),我会找到事件2(0:00-2:00),只得到我感兴趣的部分(1:00-2:00);找到另一个事件2(5:00-6:00),得到我感兴趣的部分(整个事件5:00-6:00)-总共是两个小时。事件1的总时间为5小时;5小时-2小时(事件2)为3小时。

    但是,如果在指定的时间范围内有数千个事件,那么这将不起作用,因此我希望有一个不带循环(游标)的解决方案提示。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Preet Sangha    8 年前
    ;WITH CTE AS (
        SELECT 
            evnt2.id as ID, 
            sum(evnt1.duration) as Duration 
        from 
            #events evnt1
            INNER JOIN #events evnt2
                ON evnt1.id <> evnt2.id
        WHERE 
            DATEADD(second, evnt1.duration, evnt1.starttime)
            BETWEEN 
                evnt2.starttime AND DATEADD(second, evnt2.duration, evnt2.starttime)
        GROUP BY evnt2.id
    ) 
    SELECT 
        #events.duration - CTE.duration, 
        * 
    FROM 
        #events 
        INNER JOIN CTE 
            ON #events.id = CTE.id
    
        2
  •  1
  •   Andrew Carmichael    14 年前

    我能想到的最简单的方法是使用多个自连接。我之所以说multiple是因为事件2可以在事件1之前或期间开始。

    如果事件2总是在事件1之前开始,这里有一些代码可以回答您的问题。

    select DateDiff(s,e1.StartTime, DateAdd(s,e2Before.Duration,e2Before.StartTime)) 
    from events e1
    join events e2Before
        on (e1.StartTime between e2Before.StartTime and DateAdd(s,e2Before.duration,e2Before.StartTime))
        and e1.event = 1
        and e2Before.event = 2
    

    DateAdd 参数交换了一点,以适应事件2在事件1开始后开始的情况。