выберите перекрывающиеся события даты и времени с SQL - PullRequest
0 голосов
/ 20 октября 2010

У меня есть таблица SQL Events (ID int, Event int, StartTime datetime, Duration int).

Event - это код события (1 = система работает, 2 = перерыв)

Duration - это количество секунд, в течение которогособытие было активным.

Я хотел бы получить количество секунд, в течение которых событие 1 было активным, но вычесть длительность события 2 .

Например, событие 1 было с 1:00 до 6:00, событие 2 с 0:00 до 2:00 и событие 2 с 5:00 до 6:00.Общее время должно быть от 2:00 до 5:00 -> 3 часа.

Есть способ, который я могу придумать: для каждого события 1 найти все событий 2, который может пересекаться с событием 1, и для каждого события 2 в этом наборе: обрезать его продолжительность, чтобы получить только ту часть, которая была активной во время его события 1.

, например, для моегособытие 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 ]

1 голос
/ 20 октября 2010
;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
1 голос
/ 20 октября 2010

Самый простой способ, которым я могу придумать, это сделать несколько самостоятельных соединений.Я говорю несколько, потому что событие 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...