选择0计数的计数

时间:2016-01-21 21:17:54

标签: sql-server sql-server-2008

假设我有以下查询:

SELECT top (5) CAST(Created AS DATE) as DateField, 
  Count(id) as Counted
FROM Table
GROUP BY CAST(Created AS DATE)
order by DateField desc

假设它将返回以下数据集

DateField   Counted
2016-01-18  34
2016-01-17  99
2016-01-14  1
2015-12-28  1
2015-12-27  6

但是当我在某个日期有计数= 0时,我希望在结果集中得到它。例如,它应该如下所示

DateField   Counted
2016-01-18  34
2016-01-17  99
2016-01-16  0
2016-01-15  0
2016-01-14  1

谢谢!

3 个答案:

答案 0 :(得分:1)

扩展KM的答案,你需要一个类似于数字表的日期表。 网上有很多例子,但这里只是一个简单的例子。

CREATE TABLE DateList (
 DateValue DATE,
 CONSTRAINT PK_DateList PRIMARY KEY CLUSTERED (DateValue)
 )
 GO
 -- Insert dates from 01/01/2015 and 12/31/2015
 DECLARE @StartDate DATE = '01/01/2015'
 DECLARE @EndDatePlus1 DATE = '01/01/2016'
 DECLARE @CurrentDate DATE = @StartDate

 WHILE @EndDatePlus1 > @CurrentDate
    BEGIN
    INSERT INTO DateList VALUES (@CurrentDate)
    SET @CurrentDate = DATEADD(dd,1,@CurrentDate)
    END

现在你有一张桌子

enter image description here

然后您可以按如下方式重写查询:

SELECT top (5)  DateValue, isnull(Count(id),0) as Counted
FROM DateList 
LEFT OUTER JOIN Table
  on DateValue = CAST(Created AS DATE) 
GROUP BY DateValue
order by DateValue desc

两个说明: 您需要一个where子句来指定您的范围。 对演员表的加入并不理想。日期表中的类型应与常规表中的类型匹配。

答案 1 :(得分:1)

作为单个查询的另一个解决方案:

;WITH dates AS 
(
  SELECT CAST(DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY [object_id]) - 1, '2016-01-14') as date) 'date' 
  FROM sys.all_objects
) 
SELECT TOP 5 
      [date] AS 'DateField', 
      SUM(CASE WHEN Created IS NULL THEN 0 ELSE 1 END) AS 'Counted'
  FROM dates
  LEFT JOIN Table ON [date]=CAST(Created  as date)
GROUP BY [date]
ORDER BY [date]

答案 2 :(得分:1)

对于更加前卫的解决方案,您可以使用递归公用表表达式来创建日期列表。请注意:不要在日常工作中使用递归公用表表达式!它们很危险,因为很容易创建一个永不终止的。

    DECLARE @StartDate date = '1/1/2016';
    DECLARE @EndDate date = '1/15/2016';

    WITH DateList(DateValue)
    AS
    (
            SELECT DATEADD(DAY, 1, @StartDate)
            UNION ALL
            SELECT DATEADD(DAY, 1, DateValue)
            FROM DateList
            WHERE DateList.DateValue < @EndDate
    )
    SELECT DateValue, isnull(Count(id),0) as Counted
    FROM DateList 
    LEFT OUTER JOIN [Table]
      ON DateValue = CAST(Created AS DATE) 
    GROUP BY DateValue
    ORDER BY DateValue DESC