Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择SQL中的连续数字_Sql_Sql Server_Common Table Expression_Recursive Query - Fatal编程技术网

选择SQL中的连续数字

选择SQL中的连续数字,sql,sql-server,common-table-expression,recursive-query,Sql,Sql Server,Common Table Expression,Recursive Query,这感觉很简单,但我在任何地方都找不到答案。 我正在尝试按时间为每小时运行一个查询。所以我在按小时分组,但不是所有的小时都有数据,所以有一些差距。我想每小时显示一次,不管是否有数据 下面是一个示例查询: 选择DATEPARTHOUR,DATEADDHH,-5,CreationDate作为小时, 计数*作为计数 根据评论 其中UserId=UserId 按日期分组PartHour、DATEADDHH、-5、CreationDate 我的想法是加入到一个已经有数字1到24的表中,这样传入的数据就可以放

这感觉很简单,但我在任何地方都找不到答案。 我正在尝试按时间为每小时运行一个查询。所以我在按小时分组,但不是所有的小时都有数据,所以有一些差距。我想每小时显示一次,不管是否有数据

下面是一个示例查询:

选择DATEPARTHOUR,DATEADDHH,-5,CreationDate作为小时, 计数*作为计数 根据评论 其中UserId=UserId 按日期分组PartHour、DATEADDHH、-5、CreationDate 我的想法是加入到一个已经有数字1到24的表中,这样传入的数据就可以放在它的位置上

我可以用CTE做这个吗

以小时为单位 选择i作为小时-对此不确定 从[1,2,3…24],-对此不确定 评论 选择DATEPARTHOUR,DATEADDHH,-5,CreationDate作为小时, 计数*作为计数 根据评论 其中UserId=UserId 按日期分组PartHour、DATEADDHH、-5、CreationDate 选择h.小时,c.计数 从小时到小时 小时数=小时数时数
下面是一个示例,您可以使用表值构造函数:

with hours as (
    SELECT hr
    FROM  (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) AS b(hr) 
)
etc..
还可以使用永久性辅助编号表


基本思想是正确的,但是您需要执行左连接而不是标准连接。使用左连接的原因是您希望从左侧获得答案

关于如何创建原始工时表,您可以使用以下方法直接创建它:

SELECT 1 as hour
UNION ALL
SELECT 2 as hour
  ...
UNION ALL
SELECT 24 as hour

或者,您可以创建一个用这些值填充的永久表。我不记得SqlServer上是否有更好的方法来实现这一点,或者是否允许选择一个值,但不允许从表中选择。在Oracle上,您可以从内置表“dual”中进行选择,这是一个包含单行的表。

您可以使用递归查询来构建包含任意数字的表。我们24点在这里停。然后将其加入到您的评论中,以确保每个小时都有代表性。如果你愿意,你可以很容易地把这些转化为时间。我还改变了你使用的小时作为列名,因为它是一个关键字

;with dayHours as (
    select 1 as HourValue
    union all select hourvalue + 1
    from dayHours
    where hourValue < 24
)
,
CommentTimes As (
       SELECT DATEPART(HOUR, DATEADD(HH,-5, CreationDate)) As HourValue,
              COUNT(*) AS Count
       FROM Comments
       WHERE UserId = ##UserId##
       GROUP BY DATEPART(HOUR, DATEADD(HH,-5, CreationDate)))
SELECT h.Hour, c.Count
FROM dayHours h
left JOIN CommentTimes c ON h.HourValue = c.HourValue

使用递归CTE生成小时数:

with hours as (
      select 1 as hour
      union all
      select hour + 1
      from hours
      where hour < 24
     )
. . .

作为对这个问题更一般的抽象,您可以创建Brad和Gordon用递归CTE建议的连续数字,如下所示:

WITH Numbers AS (
    SELECT 1 AS Number
    UNION ALL SELECT Number + 1
    FROM Numbers
    WHERE Number < 1000
)
SELECT * FROM Numbers
OPTION (MaxRecursion 0)
请注意,如果您计划超过100个数字,则需要在查询末尾添加选项MaxRecursion 0以防止出现错误


在不使用sql server递归CTE的情况下填充或使用下面的演示时,通常可以看到这种技术

select h.hour ,c.count
from (
    select top 24 number + 1 as hour from master..spt_values 
    where type = 'P'
) h 
left join (
    select datepart(hour, creationdate) as hour,count(1) count
    from comments
    where userid = '9131476'
    group by datepart(hour, creationdate)
) c on h.hour = c.hour
order by h.hour;
select h.hour ,c.count
from (
    select top 24 number + 1 as hour from master..spt_values 
    where type = 'P'
) h 
left join (
    select datepart(hour, creationdate) as hour,count(1) count
    from comments
    where userid = '9131476'
    group by datepart(hour, creationdate)
) c on h.hour = c.hour
order by h.hour;