自定义SQL日历

时间:2015-02-01 19:40:18

标签: sql-server

SQL Server 2005中如何创建自定义日历以仅显示Month& Year指定的日期范围。样本输出将是

Declare @startdate DateTime, @enddate DateTime;
Select @startdate = '2014-01-01', @enddate = '2018-12-31'



Month    Year
January  2014
February 2014
March    2014
April    2014
May      2014
June     2014
July     2014
August   2014
September2014 
October  2014
November 2014
December 2014

....继续执行日历中列出的其他年份。

EDIT 并且每年每3个月有一个季度,所以你会在日历中看到

Q1   ---- 2014
January ---- 2014
February ---- 2014
March ---- 2014
Q2 ---- 2014

等。等

2 个答案:

答案 0 :(得分:0)

您可以使用以下recursive CTE

Declare @startdate DateTime, @enddate DateTime;
Select @startdate = '2014-01-01', @enddate = '2018-12-31'

;WITH Calendar AS (
   SELECT DATENAME(month, @startdate) AS [Month],
          YEAR(@startdate) AS [Year],
          d = @startdate           

   UNION ALL   

   SELECT DATENAME(month, DATEADD(month, 1, d)) AS [Month],
          YEAR(DATEADD(month, 1, d)) AS [Year],                     
          d = DATEADD(month, 1, d)
   FROM Calendar
   WHERE DATEADD(month, 1, d) <= @enddate
)
SELECT [Month], [Year]
FROM Calendar

CTE锚点成员只是开始日期。 CTE递归成员不断将下个月添加到结果集,直到结束日期为止。

上述查询产生的结果集是:

Month    Year
==================
January  2014
February 2014
March    2014
....
November 2018
December 2018

修改

如果要将季度添加到结果集中,会有点复杂:

Declare @startdate DateTime, @enddate DateTime;
Select @startdate = '2014-01-01', @enddate = '2018-12-31'

;WITH Calendar AS (
   SELECT CAST('Q1' AS VARCHAR(10)) AS [Month],
          CAST('2014' AS CHAR(4)) AS [Year],
          d =  DATEADD(month, -1, @startdate),
          CAST(0.5 AS FLOAT) AS rn

   UNION ALL   

   SELECT (CASE WHEN rn = 12 THEN CAST('Q1' AS VARCHAR(10))
                WHEN FLOOR(rn) = rn AND CAST(rn AS INT) % 3 = 0 
                  THEN CAST('Q' + CAST(rn / 3 + 1 AS VARCHAR(10)) AS VARCHAR(10)) 
                ELSE CAST(DATENAME(month, DATEADD(month, 1, d)) AS VARCHAR(10)) 
          END) AS [Month],
          CAST(YEAR(DATEADD(month, 1, d)) AS CHAR(4)) AS [Year],                     
          d = CASE WHEN FLOOR(rn) = rn AND CAST(rn AS INT) % 3 = 0 THEN d
                   ELSE DATEADD(month, 1, d)
               END,
          rn = CASE WHEN rn = 12 THEN 0.5
                    WHEN FLOOR(rn) = rn AND CAST(rn AS INT) % 3 = 0 THEN rn + 0.5
                    WHEN FLOOR(rn) < rn THEN rn + 0.5                    
                    ELSE rn + 1
               END     
   FROM Calendar
   WHERE DATEADD(month, 1, d) <= @enddate
)
SELECT [Month], [Year]
FROM Calendar

<强>输出:

Month     Year
==============
Q1        2014
January   2014
February  2014
March     2014
Q2        2014
April     2014
.....
Q3        2018
July      2018
August    2018
September 2018
Q4        2018
October   2018
November  2018
December  2018

答案 1 :(得分:0)

Giorgos答案是最好的解决方案,但这个也会有效......

Declare @begin DateTime, @end DateTime
Select @begin = '2011-01-01', @end = '2014-12-31'

Create Table MonthYear
(Year Int, Month varchar(1000))

While @begin <= @end
Begin
  Insert Into dbo.MonthYear (Year, Month)
  Select DatePart(yy, @begin) As Year,
  DateName(MM, @begin) As Month
  Set @begin = DateAdd(Month, 1, @begin)
End