Как суммировать перекрывающиеся интервальные части в sql

У меня есть 2 таблицы интервалов времени. Один из них - график, другой - знак входа и выхода из системы. Мне нужно увидеть перекрывающиеся интервалы и суммировать части, где они перекрываются. Есть ли эффективный способ сделать это. В настоящее время я пытаюсь сделать следующее. Но он не работает, когда вход и выход запускаются до и после сегмента. Это означало, что они были подписаны на все время сегмента. В настоящее время он возвращает 0, когда это должно быть время всего сегмента. Я знаю, что делаю это неправильно, пытаясь понять, есть ли образец, за которым я должен следовать. SQL запутывает это, я считаю. Это то, что я пытаюсь суммировать:

Этот SQL получает сегменты, которые перекрываются. Теперь, когда у меня есть их, мне нужен выбранный фрагмент, чтобы суммировать перекрывающиеся фрагменты. Я не знаю, есть ли одно уравнение, которое это сделает.

FROM SCRD.APEMPSTAT
INNER JOIN AMS.EwfmSegmentData
ON SCRD.APEMPSTAT.Resource_XID = AMS.EwfmSegmentData.Resource_XID
 AND SCRD.APEMPSTAT.SignIn < AMS.EwfmSegmentData.StopDate
 AND SCRD.APEMPSTAT.SignOut > AMS.EwfmSegmentData.StartDate
INNER JOIN SCRD.SEGAP
ON AMS.EwfmSegmentData.CODE = SCRD.SEGAP.CODE
WHERE persp_ap = 'NO'
2 ответа

Посмотрев мой собственный образ. Думаю, я это решил. SQL выглядит так.

DATEDIFF(s, CASE 
 WHEN Startdate > SignIn
 THEN StartDate
 ELSE SignIn
 END, CASE 
 WHEN StopDate < SignOut
 THEN StopDate
 ELSE Signout
 END)

Это сводится к наименьшему из B и Y минус больше A или X. Я просто пошел один за другим и сделал уравнение, которое я использовал бы: 1. BX 2. YA 3. YX 4. BA Из этого я понял, что начало было всегда B или Y, а минусовая часть всегда была X или A. Затем я посмотрел, почему я выбрал каждого. Отсюда и меньшая и большая часть. Надеюсь, это поможет кому-то другому. Эта датированная часть - это то, что я хочу зазор в секундах.


Я бы избавился от

AND SCRD.APEMPSTAT.SignIn < AMS.EwfmSegmentData.StopDate
AND SCRD.APEMPSTAT.SignOut > AMS.EwfmSegmentData.StartDate

в вашем соединении и сделайте это в предложении WHERE, чтобы сделать его более читаемым.

Вот что я бы поставил в ГДЕ:

AND ((SCRD.APEMPSTAT.SignIn 
 BETWEEN AMS.EwfmSegmentData.StartDate AND AMS.EwfmSegmentData.StopDate) OR
 (SCRD.APEMPSTAT.SignOut 
 BETWEEN AMS.EwfmSegmentData.StartDate AND AMS.EwfmSegmentData.StopDate) OR
 (SCRD.APEMPSTAT.SignIn < AMS.EwfmSegmentData.StartDate AND
 SCRD.APEMPSTAT.SignOut > AMS.EwfmSegmentData.StopDate))

Я уверен, что есть способ избавиться от некоторых из них, но это должно получить записи, которые вы ищете.

licensed under cc by-sa 3.0 with attribution.