CTE(递归)的结果不一致

时间:2019-03-14 14:16:06

标签: sql sql-server tsql common-table-expression

我正在用这个拉头发!

我有一个每天运行的存储过程:

-- DECLARING DATE VARIABLES
    DECLARE @FirstDay date 
-- SETTING UP INITIAL VALUES TO DATE VARIABLES
    SET @FirstDay = (SELECT MIN(WK_Start) AS FirstDay FROM [TML_RDB].[COMPANY].[COMPANY_CALENDAR]);


    -- CREATE DATE RANGE FROM @FIRST DAY
    WITH DateRange AS (
    SELECT @FirstDay AS [Date]
    UNION ALL
    SELECT DATEADD("dd",1,[Date]) FROM DateRange
    WHERE [Date] < DATEADD("dd",-1,DATEFROMPARTS(YEAR(GETDATE())+2,3,1)) 
    )

    SELECT CAST(CONCAT(YEAR(DR.[Date]),FORMAT(MONTH(DR.[Date]),'00'),FORMAT(DAY(DR.[Date]),'00')) AS int) AS [DateKey]
    ,DR.[Date]
    ,DATENAME(DW,DR.[Date]) AS [DayOfWeekName]  
    ,CONCAT(RIGHT(YEAR(DR.[Date]),2), FORMAT(DATEPART(WK, DATEADD("dd",-1,DR.[Date])),'00')) AS [CalendarWeek]
    ,CONCAT('W', RIGHT(YEAR(DR.[Date]),2), FORMAT(DATEPART(WK, DATEADD("dd",-1,DR.[Date])), '00')) AS [CalendarWeekName]
    ,(DATEPART(DW, DR.[Date])+5) % 7 + 1 AS [DayOfCalendarWeek]
    --,DATEPART(WK, DATEADD("dd",-1,DR.[Date])) AS [CalendarWeek]
    ,MONTH(DR.[Date]) AS [CalendarMonth]
    ,DATENAME(MM, DR.[Date]) AS [CalendarMonthName]
    ,DATEPART(DD,DR.[Date]) AS [DayOfCalendarMonth]
    ,DATEPART(QQ,DR.[Date]) AS [CalendarQuarter]
    ,CONCAT('Q', DATEPART(QQ,DR.[Date])) AS [CalendarQuarterName]
    ,ROW_NUMBER() OVER (PARTITION BY YEAR(DR.[Date]), DATEPART(QQ,DR.[Date])  ORDER BY DR.[Date]) AS [DayOfCalendarQuarter]
    ,CASE 
        WHEN MONTH(DR.[Date]) < 7 THEN 1
        ELSE 2
    END AS [CalendarHalf]
    ,CASE 
        WHEN MONTH(DR.[Date]) < 7 THEN CONCAT('H',1)
        ELSE CONCAT('H',2)
    END AS [CalendarHalfName]
    ,CASE 
        WHEN YEAR(DR.[Date]) = 2009 
        THEN ROW_NUMBER() OVER (PARTITION BY YEAR(DR.[Date]), CASE WHEN MONTH(DR.[Date]) < 7 THEN 1 ELSE 2 END ORDER BY YEAR(DR.[Date]), CASE WHEN MONTH(DR.[Date]) < 7 THEN 1  ELSE 2 END) + DATEDIFF(DD,DATEFROMPARTS(YEAR(DR.[Date]),1,1),DATEFROMPARTS(YEAR(DR.[Date]),3,1)) 
        ELSE ROW_NUMBER() OVER (PARTITION BY YEAR(DR.[Date]), CASE WHEN MONTH(DR.[Date]) < 7 THEN 1 ELSE 2 END ORDER BY YEAR(DR.[Date]), CASE WHEN MONTH(DR.[Date]) < 7 THEN 1  ELSE 2 END)
    END AS [DayOfCalendarHalf]
    ,YEAR(DR.[Date]) AS [CalendarYear]
    ,CONCAT('Y', YEAR(DR.[Date])) AS [CalendarYearName]
    ,CASE 
        WHEN YEAR(DR.[Date]) = 2009 
        THEN ROW_NUMBER() OVER (PARTITION BY YEAR(DR.[Date]) ORDER BY DR.[Date]) + DATEDIFF(DD,DATEFROMPARTS(YEAR(DR.[Date]),1,1),DATEFROMPARTS(YEAR(DR.[Date]),3,1)) 
        ELSE ROW_NUMBER() OVER (PARTITION BY YEAR(DR.[Date]) ORDER BY DR.[Date])
    END AS [DayOfCalendarYear]  
    ,CC.[WK_Code] AS [FiscalWeek]
    ,'W' + CC.[WK_Code] AS [FiscalWeekName]
    ,DATEPART(DW,DR.[Date]) AS [DayOfFiscalWeek]
    ,CC.[Sun_Period] AS [FiscalPeriod]
    ,'P' + CC.[Sun_Period] AS [FiscalPeriodName]
    ,ROW_NUMBER() OVER (PARTITION BY CC.[Sun_Period] ORDER BY CC.[Sun_Period]) AS [DayOfFiscalPeriod]
    ,CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/3 ) + 1,'00')) AS [FiscalQuater]
    ,CONCAT('Q', LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/3 ) + 1,'00')) AS [FiscalQuaterName]
    ,ROW_NUMBER() OVER (PARTITION BY CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/3 ) + 1,'00')) ORDER BY CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/3 ) + 1,'00'))) AS [DayOfFiscalQuarter]
    ,CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/6 ) + 1,'00')) AS [FiscalHalf]
    ,CONCAT('H', LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/6 ) + 1,'00')) AS [FiscalHalfName]
    ,ROW_NUMBER() OVER (PARTITION BY CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/6 ) + 1,'00')) ORDER BY CONCAT(LEFT(CC.[Sun_Period],2), FORMAT(CEILING(((CAST(Right(CC.[Sun_Period],2) AS int)) - 1)/6 ) + 1,'00'))) AS [DayOfFiscalHalf]
    ,CONCAT(LEFT(YEAR(DR.[Date]),2), LEFT(CC.[Sun_Period],2)) AS [FiscalYear]
    ,CONCAT('Y', LEFT(YEAR(DR.[Date]),2), LEFT(CC.[Sun_Period],2)) AS [FiscalYearName]
    ,ROW_NUMBER() OVER (PARTITION BY CONCAT(LEFT(YEAR(DR.[Date]),2), LEFT(CC.[Sun_Period],2)) ORDER BY CONCAT(LEFT(YEAR(DR.[Date]),2), LEFT(CC.[Sun_Period],2))) AS [DayOfFiscalYear]
    FROM DateRange DR
    INNER JOIN [TML_RDB].[COMPANY].[COMPANY_CALENDAR] CC
    ON DR.[Date] >= CC.[WK_Start] AND DR.[Date] <= CC.[WK_End]
    OPTION (MAXRECURSION 10000) 

使用存储过程运行上述查询时,我得到了一个不正确的输出:

enter image description here

此计数应重新从1开始,而不是217。

现在,奇怪的是,当我手动运行此查询时,我得到以下正确的结果:

enter image description here

一些重要信息:

  • 该查询有时会返回正确的结果,而其他时候则不会。
  • 返回正确的结果,为什么我减少行数(年)

这与递归有关,但不能完全理解。 任何帮助将不胜感激。

谢谢

0 个答案:

没有答案