0计数

0计数

问题描述:

选择计数可以说我有以下查询:0计数

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 

谢谢!

+5

想一想这一秒....如果计数为0,这意味着没有行返回。没有行,你不能得到回报。你可以做的是使用另一个表格(如Tally表格)作为查询的基础,并将左连接添加到您的计数逻辑中。这样,当这个日期没有数据时,你仍然可以获得一排。合理? –

+3

使用数字表格生成所有必要的日期,然后将您的查询添加到该日期。 –

扩展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子句指定你的范围。 演员阵容并不理想。日期表中的类型应与常规表中的类型相匹配。

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

;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] 
+0

不确定你为什么使用系统表来生成行 –

+0

我们只需要一个数字序列(或日期)。您可以像下面的答案中那样使用临时表格,或者使用任意具有大量行的表格或视图根据行号生成序列。查看sys.all_objects已经足够用于这个目的,但是你可以使用你自己的表f.e. 'SELECT TOP 1000 CAST(DATEADD(DAY,ROW_NUMBER()OVER(ORDER BY创建)-1, '2016年1月14日')作为日期) '日期' FROM Table' –

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

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