有趣的SQL加入日期之间的日期

Cod*_*ome 17 sql datetime join sql-server-2005 sql-server-2008

首先,感谢任何帮我解决这个问题的人.我正在使用SQL 2005,但如果05中没有可用的解决方案,则可以使用2008.

我有一行看起来像这样的数据:

select * from mySPtable

| myPK | Area | RequestType |  StartDate  |  EndDate  |
   1      SB        ADD        8/14/2011    8/18/2011
   2      NB        RMV        8/16/2011    8/16/2011
Run Code Online (Sandbox Code Playgroud)

所以我想做的是按天计算每个区域的总请求数.结果应该是:

|  myDate  | RequestType |  Area  | myCount |
  8/14/2011      ADD         SB        1
  8/15/2011      ADD         SB        1
  8/16/2011      ADD         SB        1
  8/16/2011      RMV         NB        1
  8/17/2011      ADD         SB        1
  8/18/2011      ADD         SB        1
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?我很难过,没有任何谷歌搜索帮助.

Tom*_*m H 10

您需要一个Calendar表,或者您可以使用CTE生成一个.一旦你有了,那么查询的其余部分应该是相当简单的.由于递归问题而且不允许使用聚合,CTE方法可能有点复杂,所以下面我使用了表变量.您还可以将其保存在数据库中的永久表中.

SET NOCOUNT ON

DECLARE @Calendar TABLE (my_date DATETIME NOT NULL)
DECLARE @date DATETIME, @max_date DATETIME

SELECT @date = MIN(StartDate), @max_date = MAX(EndDate) FROM My_Table

WHILE (@date <= @max_date)
BEGIN
    INSERT INTO @Calendar (my_date) VALUES (@date)
    SELECT @date = DATEADD(dy, 1, @date)
END

SELECT
    C.myDate,
    M.RequestType,
    M.Area,
    COUNT(*) AS myCount
FROM
    @Calendar C
INNER JOIN My_Table M ON
    M.StartDate <= C.myDate AND
    M.EndDate >= C.myDate
GROUP BY
    C.myDate,
    M.RequestType,
    M.Area
ORDER BY
    C.myDate,
    M.RequestType,
    M.Area
Run Code Online (Sandbox Code Playgroud)

根据潜在日期范围的大小,填充表变量可能需要一段时间.例如,如果范围跨越十年或两年.