Ето по-добър пример за използване на дати. Да приемем, че искаме да съставим таблица с дати. 1 ред за всеки месец за 2017 г. Създаваме @startDate
като котва и @endDate
като терминатор. Задаваме ги на 12 месеца, тъй като искаме една година. След това рекурсията ще добави един месец чрез DATEADD
функция към @startDate
докато не се срещне терминаторът в WHERE
клауза. Знаем, че ще са необходими 11 рекурсии, за да достигнем 12 месеца... тоест 11 месеца + началната дата. Ако зададем MAXRECURSION
до нещо по-малко от 11, тогава ще се провали, тъй като 11 са необходими за изпълнение на WHERE
клауза в нашия рекурсивен CTE
, това е терминаторът...
declare @startDate datetime = '20170101'
declare @endDate datetime = '20171201'
;WITH Months
as
(
SELECT @startDate as TheDate --anchor
UNION ALL
SELECT DATEADD(month, 1, TheDate) --recursive
FROM Months
WHERE TheDate < @endDate --terminator... i.e. continue until this condition is met
)
SELECT * FROM Months OPTION (MAXRECURSION 10) --change this to 11
За вашето запитване би било достатъчно просто присъединяване.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Виждам обаче, че се опитвате да върнете това в странен формат, който трябва да се обработва в каквото и приложение за отчитане, което използвате. Това ще ви доведе до затваряне без рекурсия.
with cte as(
select
firstName
,lastName
,orderDate
,productID
,dense_rank() over(order by c.id) as RN
from
customers c
inner join
orders o on o.customerID = c.id)
select distinct
firstName
,lastName
,null
,null
,RN
from
cte
union all
select
''
,''
,orderDate
,productID
,RN
from
cte
order by RN, firstName desc