【问题标题】:Grouping incident counts into 5 minute time segments将事件计数分组为 5 分钟时间段
【发布时间】:2017-04-11 05:04:39
【问题描述】:

希望有人可以协助修改以下 SQL 以实现所需输出中显示的结果。我对 TSQL 并不流利,但我知道足以做到这一点。
我的目标是统计我的事件数据,并从午夜开始将其分组为 15 分钟的时间段,但也包括零 (0),即在特定时间段内没有事件数据。

当前查询#

;With cte As
(SELECT CONVERT (varchar(5),DATEADD(minute, 15 * 
   (DATEDIFF(minute, '20000101', I.CreateTimestamp) / 15), '20000101'),108) 
    AS CreationTime, I.IncidentShortReference AS Ref
FROM Incident I
WHERE i.CreateTimestamp between DATEADD(d,-1,GETDATE()) and  GETDATE()
)
SELECT CTE.CreationTime, count(CTE.Ref) As Count
FROM cte CTE
GROUP BY CTE.CreationTime
ORDER BY CTE.CreationTime

我的结果

CreationTime    count
00:15           2
01:00           1
01:15           1
01:30           1
01:45           2
02:00           1
02:15           1
02:30           4
(Truncated)

期望的输出

CreationTime    count
00:15           2
00:30           0
00:45           0
01:00           1
01:15           1
01:30           1
01:45           2
02:00           1
02:15           1
02:30           4
02:45           0
03:00           0
(Truncated)

【问题讨论】:

  • 在此处包含示例数据和预期输出
  • 您的数据仅在同一天?如果不是,那么在 2 个不同的日子里同一时间怎么样?
  • 即使计数我也不明白它是从哪里来的......这只是一个粗略的结果
  • TriV - 与往常一样,您对问题的思考越多,您对它的思考就越多。是的,我可以看到未来在多天内按时间段对数据进行分组。

标签: sql sql-server tsql


【解决方案1】:

这使用 cte 为昨天午夜到现在之间的每个时间戳创建记录,并使用样本数据计算每个范围内的事件数量:

declare @incident table (CreateTimestamp datetime, IncidentShortReference  varchar(5))
insert into @incident values ('4/10/2017 11:11:00', 'test') 
insert into @incident values ('4/10/2017 11:12:00', 'test')
insert into @incident values ('4/10/2017 11:21:00', 'test')
insert into @incident values ('4/10/2017 11:31:00', 'test')
insert into @incident values ('4/10/2017 13:31:00', 'test')

DECLARE @dt datetime
SELECT @dt = dateadd(d, datediff(d, 0, getdate()), 0) - 1 -- yesterday at midnight

;with cte as
(
select @dt dt
union all
select DATEADD(minute, 15, dt) as Next15
FROM cte
WHERE DATEADD(minute, 15, dt) < GETDATE()
)
select convert(varchar(5), dt, 108) as CreationTime, (select count(*) FROM @incident WHERE CreateTimestamp >= dt and CreateTimestamp < dateadd(mi, 15, dt)) as count
from cte

随机间隔的样本输出:

【讨论】:

  • 这完全符合需要。我需要包含选项 (maxrecursion 0) 以防止最大递归错误
【解决方案2】:

您可以创建一个时间间隔 CTE 表,例如 this

WITH TIME_CTE
AS(
    SELECT 
        CAST('20170411 00:15:00' AS DATETIME) AS TimePeriod
    UNION ALL
    SELECT 
        DATEADD(MINUTE, 15, TimePeriod)
    FROM TIME_CTE
    WHERE
        DATEADD(MINUTE, 15, TimePeriod) < CAST('20170411 23:59:00' AS DATETIME)
)

SELECT 
    LEFT(CONVERT(VARCHAR(10),TimePeriod,108), 5) 
FROM TIME_CTE

然后将其与您的原始查询结合起来

WITH TIME_CTE
AS(
    SELECT 
        CAST('20170411 00:15:00' AS DATETIME) AS TimePeriod
    UNION ALL
    SELECT 
        DATEADD(MINUTE, 15, TimePeriod)
    FROM TIME_CTE
    WHERE
        DATEADD(MINUTE, 15, TimePeriod) < CAST('20170411 23:59:00' AS DATETIME)
), 
CTE 
AS (
SELECT CONVERT (varchar(5),DATEADD(minute, 15 * 
   (DATEDIFF(minute, '20000101', I.CreateTimestamp) / 15), '20000101'),108) 
    AS CreationTime, I.IncidentShortReference AS Ref
FROM Incident I
WHERE i.CreateTimestamp between DATEADD(d,-1,GETDATE()) and  GETDATE()
)

SELECT TIME_CTE.TimePeriod, SUM(IIF(CTE.Ref IS NULL, 0, 1)) As Count
FROM TIME_CTE 
     LEFT JOIN CTE ON CTE.CreationTime = TIME_CTE.TimePeriod
GROUP BY TIME_CTE.TimePeriod
ORDER BY TIME_CTE.TimePeriod

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2019-09-07
    • 2017-10-29
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多