按月分组在6个月范围内的sql server

时间:2015-01-28 20:38:04

标签: sql-server

我有一个按月对数据进行分组的查询,但是有些月份不会显示,因为没有数据可以显示/分组。这几个月有可能返回月份和0吗?

这是我的查询

DECLARE @IMPORT_DATE AS DATETIME
SET @IMPORT_DATE = GETDATE()

SELECT COALESCE(COUNT(*),0), RIGHT(YEAR_MONTH_VALUE,2) 
FROM VW_CALLS
WHERE CLIENT_ID = 2
AND START_DATETIME BETWEEN DATEADD("m", -5, @IMPORT_DATE) AND @IMPORT_DATE
GROUP BY YEAR_MONTH_VALUE
ORDER BY YEAR_MONTH_VALUE

然后它返回:

(No column name)    (No column name)
740                 11
1929                12
3864                01

但我想这样:

(No column name)    (No column name)
0                   08
0                   09
0                   10
740                 11
1929                12
3864                01

1 个答案:

答案 0 :(得分:1)

您可以像这样使用递归CTE

DECLARE @MonthStart CHAR(2) = '08'

;WITH MonthsRange AS (
   SELECT m = @MonthStart, rn = 1           

   UNION ALL   

   SELECT m = (CASE WHEN m = '12' THEN CAST('01' AS CHAR(2))
                    ELSE CAST(REPLICATE('0', 2 - LEN(CAST((CAST(m AS INT) + 1) AS CHAR(2)))) + 
                              CAST((CAST(m AS INT) + 1) AS CHAR(2)) AS CHAR(2))
               END),                       
          rn = rn + 1
   FROM MonthsRange
   WHERE rn < 6
)
SELECT *
FROM MonthsRange 

为了获得您希望包含在最终结果集中的所有月份:

m   rn
=======
08  1
09  2
10  3
11  4
12  5
01  6

现在,您可以针对您的查询加入上述CTE以获取所需的结果集:

;WITH MonthsRange AS (
 ... cte statements here
)
SELECT COALESCE(vw.cnt, 0) AS cnt, mr.m AS [Month]
FROM MonthsRange AS mr
LEFT JOIN (
   SELECT COALESCE(COUNT(*),0) AS cnt, RIGHT(YEAR_MONTH_VALUE,2) AS m,
          YEAR_MONTH_VALUE AS ym
   FROM VW_CALLS
   WHERE CLIENT_ID = 2 AND 
         START_DATETIME BETWEEN DATEADD("m", -5, @IMPORT_DATE) AND @IMPORT_DATE
   GROUP BY YEAR_MONTH_VALUE) AS vw ON mr.m = vw.m
ORDER BY vw.ym