需要一些逻辑指南来生成连接数据SQL Server

时间:2013-12-10 15:01:08

标签: sql-server

基于开始&年终输入和开始&结束月份输入我想生成像

这样的输出
2010-MAR 2010-APR 2010-MAY 2010-JUN 2010-JULY 2010-AUG 2010-SEP so on

这是我的脚本工作正常,但如果开始月份数大于结束月份数,则会出现逻辑问题。

DECLARE @StartYear AS INT,
        @EndYear  AS INT

DECLARE @LowerBound AS INT,
        @UpperBound  AS INT

DECLARE @StartMonth AS VARCHAR(10),
        @EndMonth  AS VARCHAR(10)

DECLARE @ConCatData VARCHAR(MAX)
SET @ConCatData=''

SET @StartYear=2009
SET @EndYear=2010

SET @StartMonth='March'
SET @EndMonth='February'

WHILE(@StartYear <= @EndYear)
BEGIN

    SET @LowerBound = CAST(MONTH('1'+@StartMonth+'00') as INT)
    SET @UpperBound = CAST(MONTH('1'+@EndMonth+'00') as INT)

    WHILE( @LowerBound <= @UpperBound )
    BEGIN
        SELECT @ConCatData=CAST(@StartYear AS VARCHAR)+'-'+ DateName( month , DateAdd( month ,@LowerBound , -1 ) )
        SET @LowerBound=@LowerBound+1
        PRINT @ConCatData
    END
    SET @StartYear=@StartYear+1
END

如果用户输入

我想要
  • 开始年份:2009年结束年:2009
  • 开始月份:MAR结束MON:SEP

然后输出

2009-MAR 2009-APR 2009-MAY 2009-JUN 2009-JUL 2009-AUG so on.... 

如果用户输入

  • 开始年份:2009年结束年:2010
  • 开始月份:MAR结束MON:FEB

然后输出

2009-MAR 2009-APR 2009-MAY 2009-JUN 2009-JUL 2009-AUG so on.... 2010-JAN 2010-FEB

我需要一些合乎逻辑的帮助。如果可能的话,请纠正我的代码或告诉我在哪里纠正我的预期输出。感谢

4 个答案:

答案 0 :(得分:2)

基于集合的解决方案如何:

declare @startYear as int = 2009
declare @startMonth as int = 3
declare @endYear as int = 2010
declare @endMonth as int = 2
;with [dates] as (
    select convert(date, cast(@startYear as varchar(5)) + 
        RIGHT('0' + cast(@startMonth as varchar(2)), 2) + '01') as [date] --start
    union all
    select dateadd(month, 1, [date])
    from [dates]
    where [date] < cast(@endYear as varchar(5)) + 
        RIGHT('0' + cast(@endMonth as varchar(2)), 2) + '01' --end
)
select cast(year([date]) as varchar(5)) + '-' + upper(left(datename(month, [date]), 3))
from [dates]
order by [date]
option (maxrecursion 0)

SQLFiddle

答案 1 :(得分:1)

@LowerBound = 3且@UpperBound = 2,因此内部WHILE循环永远不会触发。

添加条件,如果是这种情况,请将12添加到@UpperBound,

    SET @LowerBound = CAST(MONTH('1'+@StartMonth+'00') as INT)
    SET @UpperBound = CAST(MONTH('1'+@EndMonth+'00') as INT)
    if (@UpperBound < @LowerBound) set @UpperBound = @UpperBound + 12

仅供参考,DateName( month , 13 )评估到1月份。

答案 2 :(得分:1)

这应该有效

  DECLARE @StartYear AS INT,
            @EndYear  AS INT

DECLARE @LowerBound AS INT,
        @UpperBound  AS INT

DECLARE @StartMonth AS VARCHAR(10),
        @EndMonth  AS VARCHAR(10)

DECLARE @ConCatData VARCHAR(MAX)
SET @ConCatData=''

SET @StartYear=2009
SET @EndYear=2010

SET @StartMonth='MAR '
SET @EndMonth='Jan'

WHILE(@StartYear <= @EndYear)
BEGIN

    SET @LowerBound = CAST(MONTH('1'+@StartMonth+'00') as INT)
    SET @UpperBound = CAST(MONTH('1'+@EndMonth+'00') as INT)
if (@UpperBound < @LowerBound) set @UpperBound = @UpperBound + 12;

    WHILE( @LowerBound <= @UpperBound )
    BEGIN
        SELECT @ConCatData=CAST(@StartYear AS VARCHAR)+'-'+ DateName( month , DateAdd( month ,@LowerBound , -1 ) )
        SET @LowerBound=@LowerBound+1
        PRINT @ConCatData
    END
    SET @StartYear=@StartYear+1
END

    enter code here

答案 3 :(得分:0)

希望这有帮助。

DECLARE @StartYear AS INT,
        @EndYear  AS INT

DECLARE @LowerBound AS DATETIME,
        @UpperBound  AS DATETIME

DECLARE @StartMonth AS VARCHAR(10),
        @EndMonth  AS VARCHAR(10)

DECLARE @ConCatData VARCHAR(MAX)
SET @ConCatData=''

SET @StartYear=2009
SET @EndYear=2009

SET @StartMonth='March'
SET @EndMonth='September'


    SET @LowerBound = '1 '+@StartMonth+' ' + CAST(@StartYear AS char(4))
    SET @UpperBound = '1 '+@EndMonth+' ' + CAST(@EndYear AS char(4))

    WHILE( @LowerBound <= @UpperBound )
    BEGIN
        SELECT @ConCatData=CAST(Year(@LowerBound) AS CHAR(4))+'-'+ Upper(Convert(char(3), @LowerBound, 100 ))
        PRINT @ConCatData
        SET @LowerBound=DateAdd(month, 1, @LowerBound)
    END