查询结果分为三个不同的结果集,而不是一个

时间:2018-12-20 11:08:14

标签: sql-server tsql

我需要一个为期三年的月列表,但是我得到了三个不同的结果集,而不是一个列表(因此有36行)。 我是SQL Server的新手,所以在下面的逻辑中我可能是完全错误的;)。

declare @yearlist table (value int)
declare @year int
INSERT INTO @yearlist VALUES (year(getdate())-1)
INSERT INTO @yearlist VALUES (year(getdate())+0)
INSERT INTO @yearlist VALUES (year(getdate())+1)

DECLARE db_cursor CURSOR FOR  
SELECT Value FROM @yearlist
OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @year   

WHILE @@FETCH_STATUS = 0   
BEGIN   
  ;with mths as(
    select 1 as mth, DATENAME(MONTH, cast(@year*100+1 as varchar) + '01')  as monthname, RIGHT(CAST(@year AS CHAR(4)),2) AS yr2, @year as yr 
    union all
    select mth+1, DATENAME(MONTH, cast(@year*100+(mth+1) as varchar) + '01'), RIGHT(CAST(@year AS CHAR(4)),2) AS yr2, @year as yr 
    from mths where mth<12
  )
  select yr2 + RIGHT('00' + CONVERT(NVARCHAR(2), mth), 2) as monthID,  
  * from mths  

  FETCH NEXT FROM db_cursor INTO @year   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

但这是必需的数据:

1701    January     2017
1702    February    2017
1703    March       2017
1704    April       2017
1705    May         2017
etc...
1908    August      2019
1909    September   2019
1910    October     2019
1911    November    2019
1912    December    2019

年份必须是过去,当前和明年(动态)。

2 个答案:

答案 0 :(得分:3)

理想情况下,如果这将是重复的事情,可能会改变值,那么您可能需要Calendar Table

否则,您可以使用内联理货表:

DECLARE @StartYear int = 2017,
        @EndYear int = 2019;

DECLARE @StartDate date = CONVERT(varchar(4),@StartYear) + '0101',
        @EndDate date = DATEADD(YEAR,1,CONVERT(varchar(4),@EndYear) + '0101');


WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1 --10
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
    )
SELECT RIGHT(DATEPART(YEAR, V.D),2) + RIGHT('0' + CONVERT(varchar(2),DATEPART(MONTH,V.D)),2) AS YearMonth,
       DATENAME(MONTH, V.D) AS [MonthName],
       DATEPART(YEAR, V.D) AS [Year]
FROM Tally T
     CROSS APPLY (VALUES(DATEADD(MONTH, T.I, @StartDate))) V(D)
WHERE V.D < @EndDate;

此解决方案可以为您提供长达1000个月(仅83年以上)的服务,因此应该绰绰有余。

答案 1 :(得分:0)

如果您只对过去,现在和明年感兴趣,那么以下查询应该对您有用

SELECT RIGHT(YEAR(GETDATE())-1, 2) + right ('00'+ltrim(str(mth )),2 ) ,  DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE())-1  FROM  (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)
UNION ALL
SELECT RIGHT(YEAR(GETDATE()), 2) + right ('00'+ltrim(str(mth )),2 ), DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE())  FROM  (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)
UNION ALL
SELECT RIGHT(YEAR(GETDATE())+1, 2) + right ('00'+ltrim(str(mth )),2 ), DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE()) + 1  FROM  (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)