sql - 如何计算一段时间内的数字 ID

标签 sql sql-server count

我正在寻找一种方法,每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 值列表,这些值位于 TIMEStartTIMEEnd 值的范围内 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

Demo on SQLFiddle

注意:我假设您想要范围的实际时间,而不是从 1900 年初开始的时间...

关于sql - 如何计算一段时间内的数字 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60985183/

相关文章:

sql - 在 TableAU 中的计数条件下访问 2003 VBA/Sql 更新表

java - 列出不同的元素,包括 Java Streams 的计数

sql - SQL Server 2008 中的更新列

php - 如何防止 PHP 中的 SQL 注入(inject)?

sql-server - SQL Server Compact Edition 4.0 SDK?

sql-server - SQL Server 上的命令历史记录

sql - 如何统计组数?

sql - 如何在 T-SQL 中将行转换为列,并将其写入临时表?

java - 正则表达式解析数据库列,如 JDBC 结果集

sql - 选择每年的 TOP 记录