如何跳过以下查询中的重叠间隔,以获得每日准确的跟踪时间

时间:2015-09-09 10:37:56

标签: sql sql-server sql-server-2008

我有一个查询(see SQL Fiddle),用于计算每天的总跟踪时间。它工作正常,直到我发现我的数据不干净并且它有一些间隔重叠(即在某些情况下重复启动时间)。

一天有1440分钟,因此最大跟踪时间应为1440,但由于重叠间隔,在某些情况下,跟踪时间超过每天1440分钟。

如果总和超过1440,则查询将其设置为1440.但是如果值小于1440,则仍然可能是错误的。

例如

一个时间间隔是从10:00到14:00。

第二个时间间隔是从13:00到15:00。

最终结果为4 + 2 = 6小时,其中13:00至14:00之间的小时计算两次。

  

最终结果是360分钟,小于1440,但不是   正确答案,因为数据不正确。

我想要一些帮助来修复查询,以便跳过重叠并计算正确的跟踪时间。感谢

;WITH
CTE_Dates
AS
(
    SELECT
        Email
        ,CAST(MIN(StartTime) AS date) AS StartDate
        ,CAST(MAX(EndTime) AS date) AS EndDate
    FROM track
    GROUP BY Email
)
SELECT
    CTE_Dates.Email
    ,DayStart AS xDate
    -- if some intervals overlap, it is possible
    -- to get SUM more than 1440 per day
    -- truncate such values for now
    ,CASE 
    WHEN ISNULL(SUM(DATEDIFF(second, RangeStart, RangeEnd)) / 60, 0) > 1440
    THEN 1440
    ELSE ISNULL(SUM(DATEDIFF(second, RangeStart, RangeEnd)) / 60, 0) 
    END AS TrackMinutes
FROM
    Numbers
    CROSS JOIN CTE_Dates
    CROSS APPLY
    (
        SELECT
            DATEADD(day, Numbers.Number-1, CTE_Dates.StartDate) AS DayStart
            ,DATEADD(day, Numbers.Number, CTE_Dates.StartDate) AS DayEnd
    ) AS A_Date
    OUTER APPLY
    (
        SELECT
            -- MAX(DayStart, StartTime)
            CASE WHEN DayStart > StartTime THEN DayStart ELSE StartTime END AS RangeStart

            -- MIN(DayEnd, EndTime)
            ,CASE WHEN DayEnd < EndTime THEN DayEnd ELSE EndTime END AS RangeEnd
        FROM track AS T
        WHERE
            T.Email = CTE_Dates.Email
            AND T.StartTime < DayEnd
            AND T.EndTime > DayStart
    ) AS A_Track
WHERE
    Numbers.Number <= DATEDIFF(day, CTE_Dates.StartDate, CTE_Dates.EndDate)+1
GROUP BY DayStart, CTE_Dates.Email
ORDER BY DayStart;

0 个答案:

没有答案