CTE не проходит рекурсию

Я использую CTE в первый раз и сталкиваюсь с некоторыми трудностями. Я посмотрел в Интернете и пытаюсь собрать воедино примеры.

Я хочу вставить строки между каждыми двумя строками, возвращенными для учета всех дней между ними. В строке 1 есть дата (A), а в строке 2 — дата (B). Я хочу вставить строку для каждого дня между A и B, где все эти строки имеют те же значения, что и строка 1.

Если я запускаю только свое определение привязки к своим тестовым данным, я получаю 341 строку. После запуска CTE я получаю 682. Так что он запускается только один раз.

Любые предложения, которые вы можете предоставить, были бы замечательными. Спасибо.

У меня есть следующая схема таблицы:

field1 (varchar(10)) field2 (smalldatetime) field3 (numeric(18,0)) field4 (numeric(18,6)) field5 (numeric(18,6)) field6 (numeric(18,3))

Пример входной таблицы:

ABC  1-1-1990   0  0.1   0.1   0.125
ABC  1-5-1990   1  0.2   0.2   1.0
ABC  1-9-1990   0  0.3   0.3   0.750
ABC  1-13-1990  1  0.4   0.4   1.500

Я хочу превратить это в это:

ABC  1-1-1990    0  0.1   0.1   0.125
ABC  1-2-1990    0  0.1   0.1   0.125
ABC  1-3-1990    0  0.1   0.1   0.125
ABC  1-4-1990    0  0.1   0.1   0.125
ABC  1-5-1990    1  0.2   0.2   1.0
ABC  1-6-1990    1  0.2   0.2   1.0
ABC  1-7-1990    1  0.2   0.2   1.0
ABC  1-8-1990    1  0.2   0.2   1.0
ABC  1-9-1990    0  0.3   0.3   0.750
ABC  1-10-1990   0  0.3   0.3   0.750
ABC  1-11-1990   0  0.3   0.3   0.750
ABC  1-12-1990   0  0.3   0.3   0.750
ABC  1-13-1990   1  0.4   0.4   1.500

Вот мой текущий CTE:

WITH NewData (field1,field2,field3,field4,field5,field6) AS        
(        
    SELECT  m.field1,m.field2,m.field3,m.field4,m.field5,m.field6
    FROM    MyTable as m
    WHERE m.field1 is not null        
    GROUP BY m.field1,m.field2,m.field3,m.field4,m.field5,m.field6      
    UNION ALL        
    SELECT  m.field1, DATEADD(d, 1, m.field2), m.field3, m.field4, m.field5, m.field6   
    FROM MyTable as m              
)
SELECT  field1,field2,field3, field4, field5,field6    
FROM NewData
order by field1, field2
OPTION(MAXRECURSION 0)

Текущий выпуск (пропущены даты 1-3-1990, 1-4-1990, 1-7-1990, 1-8-1990, 1-11-1990, 1-12-1990):

ABC  1-1-1990    0  0.1   0.1   0.125
ABC  1-2-1990    0  0.1   0.1   0.125
ABC  1-5-1990    1  0.2   0.2   1.0
ABC  1-6-1990    1  0.2   0.2   1.0
ABC  1-9-1990    0  0.3   0.3   0.750
ABC  1-10-1990   0  0.3   0.3   0.750
ABC  1-13-1990   1  0.4   0.4   1.500

person Ken    schedule 26.07.2011    source источник


Ответы (1)


Ваш CTE в настоящее время не определен как рекурсивный, поскольку часть, которую вы считаете рекурсивной, не является таковой, поскольку она не ссылается на себя, поэтому то, что он делает, является просто обычным запросом на объединение (поэтому вы получаете больше строк, заставляя вас думать, что это рекурсивно , когда это просто союз)

http://msdn.microsoft.com/en-us/library/ms186243.aspx

WITH NewData (field1,field2,field3,field4,field5,field6) AS        
(    
SELECT  m.field1,m.field2,m.field3,m.field4,m.field5,m.field6    
FROM    MyTable as m    
WHERE m.field1 is not null            
GROUP BY m.field1,m.field2,m.field3,m.field4,m.field5,m.field6          
UNION ALL            
SELECT  m.field1, DATEADD(d, 1, m.field2), m.field3, m.field4, m.field5, m.field6       
FROM MyTable as m 
INNER JOIN NewData n on n.field1 = m.field1   
)

Я не совсем уверен, какое условие соединения вы хотите рекурсивно использовать, поэтому только что использовал field1 в примере кода, но в основном используйте это соединение, чтобы определить, как связаны строки.

person Andrew    schedule 26.07.2011
comment
Спасибо за ответ. Я пытаюсь вернуться к полю smalldatetime (field2). Я хочу получить дату строки 1, дату строки 2 и рекурсивно добавить день в строку 1, вставив строку, пока не достигну даты в строке 2. Как только дата в строке 2 будет достигнута, CTE должен перейти к строка 2 и строка 3 из исходного набора данных... и так далее - person Ken; 26.07.2011
comment
Это не совсем сработает с точки зрения рекурсии, которая должна затрагивать фактические строки, а не создавать промежуточные строки. Если у вас есть предварительно созданная таблица календаря (например, таблица чисел), вы можете взломать ее, чтобы она работала. - person Andrew; 26.07.2011