2016-05-01 2 views
2

У меня есть следующий рекурсивный SQL-запрос для создания всех дат за любой месяц, указанный в дате.Рекурсивный CTE, генерирующий дополнительную запись

Он всегда генерирует дополнительную дату (1-е из следующего месяца).

DECLARE @currentDate DATE = '2016-5-25'; 
WITH cte AS(
    SELECT DATEADD(DAY, -DATEPART(DAY, @currentDate) + 1, @currentDate) AS firstDay 
    UNION ALL 
    SELECT DATEADD(DAY, 1, firstDay) 
    FROM cte 
    WHERE DATEPART(MONTH, firstDay) = DATEPART(MONTH, @currentDate) 
) 
SELECT * FROM cte 

Что я делаю неправильно?

+0

Какая версия SQL Server вы используете –

+0

Microsoft SQL Server 2014 - 12.0.4213.0 (X64) \t 9 июня 2015 12:06:16 \t Copyright (с) Корпорация Microsoft \t Enterprise Edition (64-разрядная версия) на Windows NT 6.3 (Build 9600:) – kamalpreet

ответ

1

В Recursive CTE, рекурсивный запрос будет первым выполняется, то где положение подтверждается

Вот правильный путь

DECLARE @currentDate DATE = '2016-5-25'; 

;WITH cte AS(
    SELECT dateadd(dd,1,eomonth(@currentDate,-1)) AS fd 
    UNION ALL 
    SELECT DATEADD(DAY, 1, fd) 
    FROM cte 
    WHERE fd < eomonth(@currentDate) 
) 
SELECT * FROM cte 

Вместо этого вы можете использовать индикаторную таблицу, чтобы сделать это что путь лучше производительность по сравнению с Recursive CTE

;WITH e1(n) AS 
(
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
), -- 10 
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10 
e3(n) AS (SELECT 1 FROM e1 CROSS JOIN e2), -- 10*100 
tally as (SELECT id = ROW_NUMBER() OVER (ORDER BY n) FROM e3) 
select 
dateadd(DD,ID-1,dateadd(dd,1,eomonth(@currentDate,-1))) as Dates 
from Tally 
where dateadd(DD,ID-1,dateadd(dd,1,eomonth(@currentDate,-1)))<=eomonth(@currentDate) 
Смежные вопросы