0

可能重复:
SQL Server:即使某些天不存在数据,如何选择日期范围内的所有天

我真的不知道如何措辞这个问题,但我会尽力解释。我正在尝试使用如下查询构建一些基本报告:

SELECT COUNT(*) AS count, h_date FROM (SELECT CONVERT(VARCHAR(10), h_time, 102) AS h_date FROM hits h GROUP BY h_date ORDER BY h_date

这会返回这样的结果,我用它来构建图表:

8 2012.05.06
2 2012.05.07
9 2012.05.09

如您所见,它错过了 8 日,因为那天没有点击。有没有办法获得0没有结果的日期的值,或者我必须在事后解析结果并手动添加它们?

4

2 回答 2

1

您可以使用现有目录视图来导出开始日期和结束日期之间的连续日期范围。然后,您可以直接加入您的数据,任何缺失的日期都将显示为 0。

DECLARE @min SMALLDATETIME, @max SMALLDATETIME;

SELECT @min = MIN(h_time), @max = MAX(h_time)
  FROM dbo.hits 
  -- WHERE ?

-- or if you just want a fixed range:

-- SELECT @min = '20120101', @max = '20120131';

;WITH n(d) AS 
(
  SELECT TOP (DATEDIFF(DAY, @min, @max)+1) 
   DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY [object_id]) - 1, DATEDIFF(DAY, 0, @min))
  FROM sys.all_objects ORDER BY [object_id]
)
SELECT n.d, [count] = COUNT(h.h_time)
  FROM n
  LEFT OUTER JOIN dbo.hits AS h
  ON h.h_time >= n.d
  AND h.h_time < DATEADD(DAY, 1, n.d)
  -- AND --WHERE clause against hits?
  GROUP BY n.d;
于 2012-09-18T20:34:07.840 回答
1

我从来都不喜欢使用系统表来创建要加入的虚拟记录,但这是一种非常常见的方法。

我接受了 Aaron Bertrand 的回答,并将通用表表达式 (CTE) 改为使用递归表达式。它更快,因为它不必点击表来进行查询。并不是说以前的版本很慢。

您需要指定“OPTION (MAXRECURSION 0);” 否则会将返回的行数限制为默认值(100)。值 0 将返回无限行。

DECLARE @min SMALLDATETIME, @max SMALLDATETIME;

--SELECT @min = MIN(h_time), @max = MAX(h_time)
--  FROM dbo.hits 

SELECT @min = '20120101', @max = '20121231';


WITH recursedate(each_date, date_index) AS
(
SELECT @min, 0 

UNION ALL 
SELECT DATEADD(DAY,date_index+1,@min), date_index+1
    FROM recursedate
    WHERE DATEADD(DAY,date_index+1,@min) <= @max
)



SELECT recursedate.each_date, [count] = COUNT(h.h_time)
  FROM recursedate
  LEFT OUTER JOIN dbo.hits AS h
  ON --CONVERT(SMALLDATETIME,h.h_time) =  recursedate.dates 
  h.h_time >= recursedate.each_date
   AND h.h_time < DATEADD(DAY, 1, recursedate.each_date)
  -- AND --WHERE clause against hits?
  GROUP BY recursedate.each_date
   OPTION (MAXRECURSION 0); -- The default is 100 so you'll only get 100 dates, 0 is unlimited.
于 2012-09-19T05:11:33.190 回答