我正在寻找一种方法,每30分钟统计一段时间内id的数量。
我写了一个 SQL 查询,但结果不正确
CREATE TABLE [dbo].[#tabl]
(
[Id] [varchar](100) NULL,
[TIMEStart] [datetime] NULL,
[TIMEEnd] [datetime] NULL
) ON [PRIMARY]
INSERT INTO [dbo].[#tabl] VALUES ('1', '2020-04-01 00:05:00.000', '2020-04-01 00:10:00.000')
INSERT INTO [dbo].[#tabl] VALUES ('2', '2020-04-01 00:11:00.000', '2020-04-01 00:29:00.000')
INSERT INTO [dbo].[#tabl] VALUES ('3', '2020-04-01 00:12:00.000', '2020-04-01 00:55:00.000')
WITH CTE AS
(
SELECT
[Id],
DATEADD(MINUTE, (DATEDIFF(MINUTE, [TIMEStart], [TIMEEnd]) / 30) * 30, 0) AS RangeTime
FROM
[dbo].[#tabl]
GROUP BY
[Id], DATEADD(MINUTE, (DATEDIFF(MINUTE, [TIMEStart],[TIMEEnd]) / 30) * 30, 0)
)
SELECT numreq, RangeTime
FROM
(SELECT COUNT(DISTINCT id) AS numreq, RangeTime
FROM CTE
GROUP BY RangeTime) temp
正确结果 - 表:
numreq RangeTime
-------------------------------------
3 1900-01-01 00:00:00.000
1 1900-01-01 00:30:00.000
时间段:
1900-01-01 00:00:00.000 - includes 3 id:1, 2, 3
1900-01-01 00:30:00.000 - includes 1 id:1
最佳答案
我认为您需要创建一个 RangeTime
值列表,这些值位于 TIMEStart
和 TIMEEnd
值的范围内 tabl
(您可以使用递归 CTE 执行此操作),然后您可以 JOIN
在重叠的时间范围内将列表返回 tabl
并计算数量与每个 RangeTime
重叠的行数:
WITH CTE AS (
SELECT DATEADD(MINUTE,(DATEDIFF(MINUTE, 0, MIN([TIMEStart]))/30)*30,0) as RangeTime,
MAX([TIMEEnd]) AS MaxTime
FROM [dbo].[tabl]
UNION ALL
SELECT DATEADD(MINUTE, 30, RangeTime), MaxTime
FROM CTE
WHERE DATEADD(MINUTE, 30, RangeTime) < MaxTime
)
SELECT RangeTime, COUNT(tabl.Id) AS numreq
FROM CTE
LEFT JOIN tabl ON tabl.TIMEStart < DATEADD(MINUTE, 30, RangeTime)
AND RangeTime <= tabl.TIMEEnd
GROUP BY RangeTime
输出:
RangeTime numreq
2020-04-01T00:00:00Z 3
2020-04-01T00:30:00Z 1
注意:我假设您想要范围的实际时间,而不是从 1900 年初开始的时间...
关于sql - 如何计算一段时间内的数字 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60985183/