Подсчет количества вхождений в час между двумя датами SQL Server - PullRequest
0 голосов
/ 08 сентября 2018

Я создал временную таблицу #MB, которая имеет идентификатор записи (119 строк), дату начала и окончания (частичный снимок экрана списка ниже):

enter image description here

Я пытаюсь получить число вхождений, которые происходили каждый час для каждого идентификатора записи в течение начальной и конечной даты (или количество вхождений каждый час, когда ID был активным между двумя датами).

Я использовал этот код:

SELECT *  
FROM  
    (SELECT  
         ISNULL(CAST(part AS VARCHAR(5)), 'Total') AS part,
         COUNT(*) AS part_count
     FROM    
         (SELECT DATEPART([HOUR], [Start]) AS part
          FROM #MB) grp
     GROUP BY
         GROUPING SETS((part),())
    ) pre
PIVOT   
    (MAX(part_count) 
         FOR part IN ([0], [1], [2], [3], [4], [5], [6], [7], [8],
                      [9], [10], [11], [12], [13], [14], [15], [16],
                      [17], [18], [19], [20], [21], [22], [23], Total)
    ) pvt;

но он учитывает только записи, основанные на дате начала (не считайте каждый час между двумя датами), и я застрял на том, как генерировать вхождения в час для каждого идентификатора между двумя датами, которые я позже смогу использовать для предварительной агрегации и стержень.

enter image description here

1 Ответ

0 голосов
/ 08 сентября 2018

сначала нужно сгенерировать список строк для каждого часа

здесь я использую рекурсивный запрос cte, чтобы сделать это

; with MB as
(
    select  ID, [Start], [End], [Date] = [Start]
    from    #MB

    union all

    select  ID, [Start], [End], [Date] = dateadd(hour, 1, convert(date, c.[Date]))
    from    MB c
    where   dateadd(hour, 1, c.[Date])  < [End]
)
select  *
from    MB

так что в вашем сводном запросе просто измените на

; with MB as
(
    select  ID, [Start], [End], [Date] = [Start]
    from    #MB

    union all

    select  ID, [Start], [End], [Date] = DATEADD(HH,DATEPART(HH,[Start]),CAST(CAST([Start] AS DATE) AS DATETIME))
    from    MB c
    where   dateadd(hour, 1, c.[Date])  < [End]
)
SELECT  *  
FROM    (
            SELECT  ISNULL(CAST(part AS VARCHAR(5)), 'Total')   AS part,
                    COUNT(*)            AS part_count
            FROM    (
                        SELECT  DATEPART([HOUR], [Date]) AS part
                        FROM    MB   -- changed to the cte
                    ) grp
            GROUP BY
                    GROUPING SETS((part),())
        ) pre
PIVOT   (MAX(part_count) FOR part IN (
            [0],[1],[2],[3],[4],[5],[6],[7],[8],
            [9],[10],[11],[12],[13],[14],[15],[16],
            [17],[18],[19],[20],[21],[22],[23], Total)) pvt;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...