SQL计数记录,按日期分组并填写缺少日期?

时间:2014-02-06 13:54:47

标签: sql

我有以下SQL查询计算订单并按每天(日期)对它们进行分组。

因此得出以下结果:

01/02/2014 = 10
02/02/2014 = 2
05/02/2014 = 7
07/02/2014 = 4

查询:

SELECT TOP(@NumberOfRecords) DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) AS Date,       COUNT(DISTINCT ID) AS Count 
          FROM OrderSpecs
          GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) 
          ORDER BY Date DESC

我的问题是,如何让我的查询填写任何中间缺失日期并将Count值设置为0?

所需结果示例:

    01/02/2014 = 10
    02/02/2014 = 2
    03/02/2014 = 0
    04/02/2014 = 0
    05/02/2014 = 7
    06/02/2014 = 0
    07/02/2014 = 4

非常感谢您抽出时间阅读本文。

3 个答案:

答案 0 :(得分:2)

如果您发出大量此类查询,则可以创建包含所有日历日期的日历表

CREATE TABLE calendar([date] DATE NOT NULL PRIMARY KEY);

然后使用外连接

SELECT TOP(@NumberOfRecords) 
       c.Date, COALESCE(o.Count, 0) Count
  FROM Calendar c LEFT JOIN 
(
  SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) AS Date,
         COUNT(DISTINCT ID) AS Count 
    FROM OrderSpecs
   GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) 
) o
    ON c.Date = o.Date
 ORDER BY Date DESC

输出:

|       DATE | COUNT |
|------------|-------|
| 2014-02-07 |     4 |
| 2014-02-06 |     0 |
| 2014-02-05 |     7 |
| 2014-02-04 |     0 |
| 2014-02-03 |     0 |
| 2014-02-02 |     2 |
| 2014-02-01 |    10 |

这是 SQLFiddle 演示

答案 1 :(得分:1)

DECLARE @mindate DATETIME
DECLARE @maxdate DATETIME
DECLARE @diff INT
SELECT @maxdate = MAX(addeddate), @mindate = MIN(addeddate) FROM OrderSpecs
SET @diff = DATEDIFF(DAY,  @mindate,@maxdate)
;WITH cte(dt,level)
AS
(
    SELECT  @mindate AS dt, 0 AS level 
    UNION ALL
    SELECT DATEADD(day,1,cte.dt),level + 1 from cte WHERE level < @diff
)
SELECT dt,c FROM cte
LEFT JOIN 
(
   SELECT DATEADD(dd, 0, DATEDIFF(dd, 0,AddedDate)) AddedDt, COUNT(ID) AS c  
   FROM OrderSpecs 
   GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0,AddedDate))
) tab
ON cte.dt = tab.AddedDt 
OPTION (MaxRecursion 32767);

编写CTE以生成日期范围内的所有日期。这样就完成了LEFT JOIN聚合结果集。

免责声明:如果日期范围超过32767天

,则此查询无效

答案 2 :(得分:0)

你可以做一些事情。我没有对它进行过彻底的测试,但原则上如果你正在加入它,那么它将会成功。您可能需要对输出执行命令以使其按正确顺序排列

SELECT SS1.Date, Count
FROM
( 
DECLARE @mindate Date
DECLARE @maxdate Date
WITH DateTable
AS
(
     SELECT CAST(@mindate as Date) AS [DATE]
     UNION ALL
     SELECT DATEADD(dd, 1, [DATE]) FROM DateTable 
     WHERE DATEADD(dd, 1, [DATE]) BETWEEN @mindate AND @maxdate
)
SELECT dt.[DATE], 0 [Count] FROM [DateTable] dt
UNION ALL

TOP(@NumberOfRecords) DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) AS Date,           COUNT(DISTINCT ID) AS Count 
      FROM OrderSpecs
      GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, AddedDate)) 
      ORDER BY Date DESC
) SS1
ORDER BY [Date]

您是否可能知道可以作为种子日期传递的开始日期和结束日期?