我正在尝试编写一个查询来显示一天中每个小时的用户数。如果该小时没有数据,我想以零计数记录该小时。
\n\n\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 userId \xe2\x95\x91 creationDate \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 1 \xe2\x95\x91 2014-10-08 14:33:20.763 \xe2\x95\x91\n\xe2\x95\x91 2 \xe2\x95\x91 2014-10-09 04:24:14.283 \xe2\x95\x91\n\xe2\x95\x91 3 \xe2\x95\x91 2014-10-10 18:34:26.260 \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d \nRun Code Online (Sandbox Code Playgroud)\n\n\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 Date \xe2\x95\x91 UserCount \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 2014-10-08 01:00:00.000 \xe2\x95\x91 1 \xe2\x95\x91\n\xe2\x95\x91 2014-10-08 02:00:00.000 \xe2\x95\x91 1 \xe2\x95\x91\n\xe2\x95\x91 2014-10-08 03:00:00.000 \xe2\x95\x91 0 \xe2\x95\x91\n\xe2\x95\x91 2014-10-08 04:00:00.000 \xe2\x95\x91 1 \xe2\x95\x91\n\xe2\x95\x91 .... \xe2\x95\x91 \xe2\x95\x91\n\xe2\x95\x91 ..... \xe2\x95\x91 \xe2\x95\x91\n\xe2\x95\x91 2014-10-10 23:00:00.000 \xe2\x95\x91 1 \xe2\x95\x91\n\xe2\x95\x91 2014-10-10 00:00:00.000 \xe2\x95\x91 0 \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\nRun Code Online (Sandbox Code Playgroud)\n\nSELECT\n CAST(creationDate as date) AS ForDate, \n DATEPART(hour,date) AS OnHour, \n COUNT(distinct userId) AS Totals\nFROM Table\nwhere primaryKey= 123\nGROUP BY\n CAST(creationDate as date), \n DATEPART(hour, createDate);\nRun Code Online (Sandbox Code Playgroud)\n\n这仅给我提供了每小时存在的记录的计数,而没有提供缺失时间的计数。我认为有一种方法可以通过使用交叉连接来将缺失的时间计数为零。
\n\n我遇到过这样的事情,但无法用它构建正确的查询:
\n\ncross join (select ROW_NUMBER() over (order by (select NULL)) as seqnum\nfrom INFORMATION_SCHEMA.COLUMNS) hours where hours.seqnum <= 24 \nRun Code Online (Sandbox Code Playgroud)\n\n我不是 SQL 专家,但我正在努力构建这个结果集。
\n\nwith dh as (\n select DATEADD(hour, seqnum - 1, thedatehour ) as DateHour \n from (select distinct cast(cast(createDate as DATE) as datetime) as thedatehour\n from Table a \n ) a \n cross join\n (select ROW_NUMBER() over (order by (select NULL)) as seqnum\n from INFORMATION_SCHEMA.COLUMNS\n ) hours\n where hours.seqnum <= 24\n )\nselect dh.DateHour, COUNT(distinct c.userId) \nfrom dh cross join Table c\n--on dh.DateHour = c.createDate\ngroup by dh.DateHour\norder by 1\nRun Code Online (Sandbox Code Playgroud)\n
获取已有的查询并捕获临时表中的输出#T。
select cast(T.creationDate as date) as ForDate,
datepart(hour, T.creationDate) as OnHour,
count(distinct T.userId) as Totals
into #T
from dbo.T
group by cast(T.creationDate as date),
datepart(hour, T.creationDate)
Run Code Online (Sandbox Code Playgroud)
从一天的小时列表中获取不同的ForDate值并交叉应用,然后左外连接以获取每个小时的值。#T#TTotals
select dateadd(hour, H.OnHour, cast(D.ForDate as datetime)) as ForDate,
isnull(T.Totals, 0) as Totals
from (select distinct T.ForDate from #T as T) as D
cross apply (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),
(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)) as H(OnHour)
left outer join #T as T
on H.OnHour = T.OnHour and
D.ForDate = T.ForDate
drop table #T
Run Code Online (Sandbox Code Playgroud)