我在查询时遇到问题,必须计算行数并返回数字作为结果。关键是我需要最近 24 小时的数据除以一小时的时间段。我已经使用 UNION ALL 完成了这个查询 24 次,但是 SQL 单个查询有 800 多行(令人惊讶的是只需要 3 秒)。我知道我可以以某种方式按时间分组,但不知道如何正确执行。我坚信相等查询只需大约 20-30 行 SQL。我将不胜感激任何线索。这里您有我提到的一些简化查询。
长查询(使用 UNION ALL):
DECLARE @CurrentTime datetime = GETDATE();
--Data from 1 hour
SELECT
----Time
(SELECT CONVERT(VARCHAR(5), (DATEADD(HOUR, -1, @CurrentTime)), 114)) AS [Time],
----Count on 1st table
(SELECT COUNT(T1.[TableFirstId])
FROM [dbo].[Table1] AS T1
WHERE T1.[IncomingDate] BETWEEN (DATEADD(HOUR, -1, @CurrentTime)) AND @CurrentTime) AS [CountT1],
----Count on 2nd table
(SELECT COUNT(T2.[TableSecondId])
FROM [dbo].[Table2] AS T2
WHERE T2.[IncomingDate] BETWEEN (DATEADD(HOUR, -1, @CurrentTime)) AND @CurrentTime) AS [CountT2],
----Count on 3rd table
(SELECT COUNT(T3.[TableThirdId])
FROM [dbo].[Table3] AS T3
WHERE T3.[IncomingDate] BETWEEN (DATEADD(HOUR, -1, @CurrentTime)) AND @CurrentTime) AS [CountT3]
UNION ALL
--Data from 2 hours
SELECT
----Time
(SELECT CONVERT(VARCHAR(5), (DATEADD(HOUR, -2, @CurrentTime)), 114)) AS [Time],
----Count on 1st table
(SELECT COUNT(T1.[TableFirstId])
FROM [dbo].[Table1] AS T1
WHERE T1.[IncomingDate] BETWEEN (DATEADD(HOUR, -2, @CurrentTime)) AND (DATEADD(HOUR, -1, @CurrentTime))) AS [CountT1],
----Count on 2nd table
(SELECT COUNT(T2.[TableSecondId])
FROM [dbo].[Table2] AS T2
WHERE T2.[IncomingDate] BETWEEN (DATEADD(HOUR, -2, @CurrentTime)) AND (DATEADD(HOUR, -1, @CurrentTime))) AS [CountT2],
----Count on 3rd table
(SELECT COUNT(T3.[TableThirdId])
FROM [dbo].[Table3] AS T3
WHERE T3.[IncomingDate] BETWEEN (DATEADD(HOUR, -2, @CurrentTime)) AND (DATEADD(HOUR, -1, @CurrentTime))) AS [CountT3]
UNION ALL
--Data from 3 hours
SELECT
----Time
(SELECT CONVERT(VARCHAR(5), (DATEADD(HOUR, -3, @CurrentTime)), 114)) AS [Time],
----Count on 1st table
(SELECT COUNT(T1.[TableFirstId])
FROM [dbo].[Table1] AS T1
WHERE T1.[IncomingDate] BETWEEN (DATEADD(HOUR, -3, @CurrentTime)) AND (DATEADD(HOUR, -2, @CurrentTime))) AS [CountT1],
----Count on 2nd table
(SELECT COUNT(T2.[TableSecondId])
FROM [dbo].[Table2] AS T2
WHERE T2.[IncomingDate] BETWEEN (DATEADD(HOUR, -3, @CurrentTime)) AND (DATEADD(HOUR, -2, @CurrentTime))) AS [CountT2],
----Count on 3rd table
(SELECT COUNT(T3.[TableThirdId])
FROM [dbo].[Table3] AS T3
WHERE T3.[IncomingDate] BETWEEN (DATEADD(HOUR, -3, @CurrentTime)) AND (DATEADD(HOUR, -2, @CurrentTime))) AS [CountT3]
UNION ALL
--(etc...)
这个查询给了我类似的东西:
Time | CountT1 | CountT2 | CountT3
21:05 | 3215467 | 3456364 | 3234234
20:05 | 2253221 | 3123123 | 3238291
19:05 | 1231467 | 1232342 | 1123123
18:05 | 3112412 | 6712353 | 1233124
17:05 | 1242141 | 1241142 | 4112426
16:05 | 3123467 | 3456364 | 3234234
15:05 | 3215467 | 3412334 | 3231234
14:05 | 3324467 | 3456123 | 2312334
13:05 | 3215467 | 3456364 | 1112310
12:05 | 3215467 | 3456364 | 1231234
11:05 | 3123127 | 3456364 | 3234234
10:05 | 3215467 | 3456364 | 3234234
09:05 | 3215467 | 3456364 | 3234234
08:05 | 3215467 | 3456364 | 3234234
07:05 | 3215467 | 3456364 | 3234234
06:05 | 3215467 | 3456364 | 3234234
05:05 | 3215467 | 2212214 | 3234234
04:05 | 3215467 | 3126542 | 3234234
03:05 | 3215467 | 3123364 | 3234234
02:05 | 3215467 | 3456364 | 3234234
01:05 | 3215467 | 3456364 | 3234234
00:05 | 3215467 | 3456364 | 3123123
23:05 | 3215467 | 3456364 | 3212313
22:05 | 3223424 | 1232163 | 1235321
我需要通过更简单的查询返回相同的结果(考虑这样的事情):
DECLARE @CurrentTime datetime = GETDATE();
--Data from 24 hours
SELECT
----Count on 1st table
(SELECT COUNT(T1.[TableFirstId])
FROM [dbo].[Table1] AS T1
WHERE T1.[IncomingDate] BETWEEN (DATEADD(HOUR, -24, @CurrentTime)) AND @CurrentTime) AS [CountT1],
----Count on 2nd table
(SELECT COUNT(T2.[TableSecondId])
FROM [dbo].[Table2] AS T2
WHERE T2.[IncomingDate] BETWEEN (DATEADD(HOUR, -24, @CurrentTime)) AND @CurrentTime) AS [CountT2],
----Count on 3rd table
(SELECT COUNT(T3.[TableThirdId])
FROM [dbo].[Table3] AS T3
WHERE T3.[IncomingDate] BETWEEN (DATEADD(HOUR, -24, @CurrentTime)) AND @CurrentTime) AS [CountT3]
FROM [dbo].[Table1] AS T1
GROUP BY DATEPART(HOUR, T1.[IncomingDate])
但是它并没有按照我的预期工作。有谁能帮助我理解这一点吗?并解决我的问题?
最佳答案
此查询将为您提供与使用较少 SQL 的查询完全相同的结果。
DECLARE @HourTbl TABLE ( HourBegin DATETIME, HourEnd DATETIME)
DECLARE @i INT=0
DECLARE @dtBegin datetime
DECLARE @dtEnd datetime = GETDATE()
WHILE @i < 24
BEGIN
SET @i = (@i + 1)
SET @dtBegin = @dtEnd
SET @dtEnd = DATEADD(HOUR, -@i, @dtBegin)
INSERT INTO @HourTbl
SELECT @dtBegin, @dtEnd
END
;with hourVal ( hourBegin , hourEnd )
as
(
select hourBegin, hourend
from @HourTbl
)
select CONVERT(VARCHAR(5), hourVal.hourBegin, 114),
(
select COUNT(T1.[TableFirstId])
from Table1
where T1.[IncomingDate] BETWEEN hourVal.hourBegin, hourVal.hourEnd
),
(
select COUNT(T1.[TableFirstId])
from Table2
where T1.[IncomingDate] BETWEEN hourVal.hourBegin, hourVal.hourEnd
)
关于sql - 按小时分组计数(从-到),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25796048/