【发布时间】:2012-09-07 21:01:00
【问题描述】:
由于某种原因,我在使用此查询时发现我的时间间隔存在差距。仅使用基本数据时,我就可以使用它。但是,当加入我的表并指定 WHERE 子句时,我看到我的时间间隔有间隙。我还需要将 S.SessionEndTime 合并到我的时间间隔中,以查找与 ResponseTime 和 SessionEndTime 之间的给定 1 分钟时间间隔重叠的记录计数。
这是我正在使用的查询。通过使用派生表,我在 1 分钟间隔内基于 COUNT 获得每小时 MAX。
DECLARE @start_date DATETIME
DECLARE @end_date DATETIME
DECLARE @interval TIME
SET @start_date = '08/01/2012'
SET @end_date = '08/01/2012 12:00:00'
SET @interval = '00:01:00.00';
WITH TimeWindowsCTE AS
(
SELECT
@start_date AS WindowStart, @start_date + @interval AS WindowEnd
UNION ALL
SELECT
SW.WindowStart + @Interval, SW.WindowEnd + @interval
FROM
TimeWindowsCTE AS SW
WHERE
SW.WindowEnd < @end_date
)
SELECT
DATEADD(hour, DATEDIFF(hour, CONVERT(datetime, '19000101', 112), t1.WindowStart), CONVERT(datetime, '19000101', 112)) WindowStart,
MAX([Sessions]) [Sessions]
FROM
(
SELECT
SW.WindowStart, COUNT(*) [Sessions]
FROM
TimeWindowsCTE AS SW
LEFT OUTER JOIN SessionDetails AS S ON SW.WindowStart <= S.ResponseTime and S.ResponseTime < SW.WindowEnd
--I need to introduce the S.SessionEndTime into the JOIN so I can count the number of records that
--fall within the interval
LEFT OUTER JOIN VoipDetails V on S.SessionIdTime = V.SessionIdTime and S.SessionIdSeq = V.SessionIdSeq
WHERE V.ToGatewayId IS NOT NULL
GROUP BY
SW.WindowStart
) t1
GROUP BY
DATEADD(hour, DATEDIFF(hour, CONVERT(datetime, '19000101', 112), t1.WindowStart), CONVERT(datetime, '19000101', 112))
ORDER BY
DATEADD(hour, DATEDIFF(hour, CONVERT(datetime, '19000101', 112), t1.WindowStart), CONVERT(datetime, '19000101', 112))
OPTION (maxrecursion 0)
这是我得到的输出
日期会议 2012-08-01 00:00:00.000 5 2012-08-01 01:00:00.000 3 2012-08-01 02:00:00.000 2 2012-08-01 03:00:00.000 2 2012-08-01 05:00:00.000 1 2012-08-01 06:00:00.000 2 2012-08-01 07:00:00.000 3 2012-08-01 08:00:00.000 2 2012-08-01 09:00:00.000 2 2012-08-01 10:00:00.000 1对于 04:00:00 时间段,我需要一个 0。我想要完成的是确定在该给定小时内发生了多少并发会话,而不是在一小时的顶部有多少会话。这就是重叠发挥作用的地方。如果在上午 8 点 56 分开始通话并在上午 9 点 26 分结束,则应该在上午 8 点钟至少有 1 个电话,在上午 9 点钟至少有 1 个电话。然后根据一天中每个小时的并发会话数,我找到给定日期的 MAX,然后在我的报告中使用它。
这是数据的基本结构:
插入@Sessions ( SessionIdSeq, ResponseTime, SessionEndTime ) 值 (1, '20120901 00:00:00', '20120901 05:59:59' ), -- 单个会话中的几个小时。 (1, '20120901 01:01:00', '20120901 01:01:30' ), -- 各种重叠... (1, '20120901 01:02:00', '20120901 01:03:30' ), -- ... 一个小时内的会话。 (1, '20120901 00:00:05.077', '20120901 00:04:02.280'), (1, '20120901 00:00:14.687', '20120901 00:06:05.947'), (1, '20120901 00:00:17.857', '20120901 00:07:34.757'), (1, '20120901 00:00:25.843', '20120901 00:07:38.720'), (1, '20120901 00:00:29.427', '20120901 00:01:58.180'), (1, '20120901 00:00:31.853', '20120901 00:05:10.733'), (1, '20120901 00:00:40.693', '20120901 00:00:44.237'), (1, '20120901 00:00:58.773', '20120901 00:06:14.667'), (1, '20120901 00:00:59.457', '20120901 00:01:01.310'), (1, '20120901 00:01:16.390', '20120901 00:11:18.383')【问题讨论】:
-
嗯,CTE 看起来很眼熟。你能展示一个输入和输出的例子,并指出似乎有什么问题吗?以及您期望
GROUP BY和ORDER BY子句执行的操作。 -
您的各种转换似乎旨在从日期/时间确定“时间的顶部”。将其放入一个明确命名的函数中将使代码更容易解释。我也会避免与文本之间的转换,而是使用更像:
declare @Now as DateTime = GetDate(); select @Now as 'Now', DateAdd( hour, DatePart( hour, @Now ), Cast( Cast( @Now as Date ) as DateTime ) ) as 'Top Of The Hour'. -
添加了我得到的输出以及我想从中得到什么。谢谢哈宝!
-
请求澄清:您是在寻找 (A) 每小时并发 会话的最大数量,还是 (B) 总数每小时活跃的会话数?例如,如果一个长会话从 8:00:00 开始并在 10:30:00 结束,而 42 个短会话从 9:nn:05 开始并在 9:nn:20 结束(其中 nn 是 01 到 42) , 那么方法 (A) 返回 8:00 1, 9:00 2, 10:00 1。方法 (B) 将返回 8:00 1, 9:00 43, 10:00 1。
-
查找每小时的最大并发会话数。这涉及许可证问题,它围绕并发会话展开。我有两份报告,一份报告包含一整天的最大并发会话数,第二份报告包含当天每小时的并发会话数
标签: tsql date common-table-expression overlapping