查找开始日期时间和结束日期时间之间与另一个表的重叠时间

时间:2019-01-14 07:59:47

标签: sql-server

需要查找重叠时间-START_DATUM和END_DATUM是datetime字段,用于保存停机时间的开始或结束日期和时间

在下面的示例中,仅内部停机时间(称为字段internalDowntime)可以与其他停机时间(称为字段OtherDowntime)重叠。最终目的是在几分钟内找到另一个字段的总重叠时间

感谢有人能帮我解决这个问题

SELECT deck.ID_DECKUNGSBEITRAG,

       (
           SELECT TOP (1)
                  DATEDIFF(MINUTE, lr.START_DATUM, lr.END_DATUM) / 60.0
           FROM dbo.LEITSTAND lr
               INNER JOIN dbo.STILLSTANDSZEIT s
                   ON lr.ID_STILLSTANDSZEIT = s.ID_STILLSTANDSZEIT
               INNER JOIN dbo.PRODUKTIONSANLAGE P
                   ON lr.ID_PRODUKTIONSANLAGE = P.ID_PRODUKTIONSANLAGE
           WHERE lr.PRODUKTION_TYP = 'S'
                 AND s.TYP = 'R'
                 AND lr.ID_PRODUKTIONSANLAGE = l.ID_PRODUKTIONSANLAGE
                 AND lr.START_DATUM < l.START_DATUM
           ORDER BY lr.START_DATUM DESC
       ) setuptime,
       DATEDIFF(MINUTE, l.START_DATUM, l.END_DATUM) / 60.0 runtime,
       (
           SELECT SUM(DATEDIFF(MINUTE, le.START_DATUM, le.END_DATUM) / 60.0)
           FROM dbo.STILLSTANDSZEIT s
               INNER JOIN dbo.LEITSTAND le
                   ON le.ID_STILLSTANDSZEIT = s.ID_STILLSTANDSZEIT
           WHERE s.ID_HERSTELLVORSCHRIFT = hs.ID_HERSTELLVORSCHRIFT
       ) internalDowntime,
       (
           SELECT SUM(DATEDIFF(MINUTE, ZEIT_VON, ZEIT_BIS) / 60.0)
           FROM dbo.PRODUKTIONSANLAGE_AUSFALLZEIT
           WHERE ZEIT_VON >= l.START_DATUM
                 AND ZEIT_VON <= l.END_DATUM
                 AND ID_PRODUKTIONSANLAGE = p.ID_PRODUKTIONSANLAGE
       ) OtherDowntime,
       p.STUNDENSATZ_GRENZKOSTEN
FROM dbo.DECKUNGSBEITRAG deck
    INNER JOIN dbo.HERSTELLVORSCHRIFT hs
        ON deck.CHARGE = hs.CHARGE_NUMMER
    INNER JOIN dbo.LEITSTAND l
        ON l.ID_HERSTELLVORSCHRIFT = hs.ID_HERSTELLVORSCHRIFT
    INNER JOIN dbo.PRODUKTIONSANLAGE p
        ON p.ID_PRODUKTIONSANLAGE = l.ID_PRODUKTIONSANLAGE        
WHERE deck.CHARGE = 'CHG0116112945'
      AND deck.ID_MANDANT = 1

3 个答案:

答案 0 :(得分:0)

查找时间重叠的算法是:

(StartA <= EndB) and (EndA >= StartB)

如您所说,您有两个桌子。因此您的查询应如下所示:

SELECT
*
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.ID = T2.T1_ID 
AND T1.StartA <= T2.EndB
AND T1.EndA >= T2.StartB

答案 1 :(得分:0)

如果有停机时间(内部停机和其他停机时间),生产时间总是包括停机时间,其想法是计算确切的生产时间,不包括停机时间。这里的问题是,内部停机时间可能与其他停机时间重叠。

SELECT runtime  ---internalDowntime-OtherDowntime AS productiontime  based on overlapping
FROM
(
    SELECT deck.ID_DECKUNGSBEITRAG, 
           DATEDIFF(MINUTE, l.START_DATUM, l.END_DATUM) / 60.0 runtime, --which includes downtime, 
    (
        SELECT SUM(DATEDIFF(MINUTE, le.START_DATUM, le.END_DATUM) / 60.0)
        FROM dbo.STILLSTANDSZEIT s
             INNER JOIN dbo.LEITSTAND le ON le.ID_STILLSTANDSZEIT = s.ID_STILLSTANDSZEIT
        WHERE s.ID_HERSTELLVORSCHRIFT = hs.ID_HERSTELLVORSCHRIFT
    ) internalDowntime, 
    (
        SELECT SUM(DATEDIFF(MINUTE, ZEIT_VON, ZEIT_BIS) / 60.0)
        FROM dbo.PRODUKTIONSANLAGE_AUSFALLZEIT
        WHERE ZEIT_VON >= l.START_DATUM
              AND ZEIT_VON <= l.END_DATUM
              AND ID_PRODUKTIONSANLAGE = p.ID_PRODUKTIONSANLAGE
    ) OtherDowntime
    FROM dbo.DECKUNGSBEITRAG deck
         INNER JOIN dbo.HERSTELLVORSCHRIFT hs ON deck.CHARGE = hs.CHARGE_NUMMER
         INNER JOIN dbo.LEITSTAND l ON l.ID_HERSTELLVORSCHRIFT = hs.ID_HERSTELLVORSCHRIFT
         INNER JOIN dbo.PRODUKTIONSANLAGE p ON p.ID_PRODUKTIONSANLAGE = l.ID_PRODUKTIONSANLAGE
    WHERE deck.CHARGE = 'CHG0116112945'
          AND deck.ID_MANDANT = 1
) temp;

日期格式为yyyy-mm-dd hh:mm:ss

Production start and endtime (runtime)

  SELECT DATEDIFF(minute,'2016-12-09 01:00:49.203','2016-12-12 22:30:04.787')/60.0       =  93.500000

Internal Downtime 第一排1小时,第二排5小时,共6小时

Other Downtime

第一行SELECT DATEDIFF(minute,'2016-12-10 06:00:00.000','2016-12-12 06:00:00.000')/60.0 =48.000000 突出显示的一个包括内部停​​机时间(除了1个小时之外,因此总共49个小时)

除了最终产量(生产时间)是93.50 – 6-49 = 38.5

答案 2 :(得分:0)

这是解决方案,

;WITH AllDownTime AS
(
    /* Overlapping DownTimeInternal DownTimeExternal */ 
    SELECT IIF(i.StartTime < e.StartTime, i.StartTime, e.StartTime) StartTime,
           IIF(i.EndTime < e.EndTime, e.EndTime, i.EndTime) EndTime
      FROM dbo.DownTimeInternal i
     INNER JOIN dbo.DownTimeExternal e
             ON i.StartTime < e.EndTime AND e.StartTime < i.EndTime  
UNION ALL
    /* Non overlapping DownTimeInternal */
    SELECT i.StartTime, i.EndTime
      FROM dbo.DownTimeInternal i
      WHERE NOT EXISTS(SELECT * 
                         FROM dbo.DownTimeExternal e
                        WHERE i.StartTime < e.EndTime AND e.StartTime < i.EndTime)
UNION ALL
    /* Non overlapping DownTimeExternal */
    SELECT e.StartTime, e.EndTime
      FROM dbo.DownTimeExternal e
     WHERE NOT EXISTS(SELECT * 
                        FROM dbo.DownTimeInternal i
                       WHERE e.StartTime < i.EndTime AND i.StartTime < e.EndTime)
)

SELECT SUM(DATEDIFF(minute,StartTime,EndTime))/60.0 
  FROM AllDownTime