Hier is een beter voorbeeld met datums. Stel dat we een tabel met datums willen maken. 1 rij voor elke maand voor het jaar 2017. We creëren een @startDate
als het anker en @endDate
als terminator. We hebben deze ingesteld op 12 maanden uit elkaar, omdat we een enkel jaar willen. Dan wordt de recursie een maand toegevoegd via de DATEADD
functie naar de @startDate
totdat de terminator is gevonden in de WHERE
clausule. We weten dat er 11 recursies nodig zijn om 12 maanden te bereiken... dat wil zeggen 11 maanden + de startdatum. Als we de MAXRECURSION
tot iets minder dan 11, dan zal het mislukken aangezien er 11 nodig zijn om te voldoen aan de WHERE
clausule in onze recursieve CTE
, dat is de terminator..
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
Voor je vraag zou een simpele join voldoende zijn.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Ik zie echter dat u dit in een vreemd formaat probeert terug te geven, wat moet worden afgehandeld in welke rapportagetoepassing u ook gebruikt. Dit zou je dichtbij brengen zonder recursie.
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