一天中每个小时的结果,即使不存在数据

Anu*_*rni 6 sql-server t-sql

我正在尝试编写一个查询来显示一天中每个小时的用户数。如果该小时没有数据,我想以零计数记录该小时。

\n\n

源数据

\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 \n
Run Code Online (Sandbox Code Playgroud)\n\n

所需输出

\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\n
Run Code Online (Sandbox Code Playgroud)\n\n

尝试1

\n\n
SELECT\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);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这仅给我提供了每小时存在的记录的计数,而没有提供缺失时间的计数。我认为有一种方法可以通过使用交叉连接来将缺失的时间计数为零。

\n\n

我遇到过这样的事情,但无法用它构建正确的查询:

\n\n
cross join (select ROW_NUMBER() over (order by (select NULL)) as seqnum\nfrom INFORMATION_SCHEMA.COLUMNS) hours where hours.seqnum <= 24 \n
Run Code Online (Sandbox Code Playgroud)\n\n

我不是 SQL 专家,但我正在努力构建这个结果集。

\n\n

尝试2:

\n\n
with 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\n
Run Code Online (Sandbox Code Playgroud)\n

Mik*_*son 5

获取已有的查询并捕获临时表中的输出#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)