Här är ett bättre exempel med datum. Antag att vi vill bygga en tabell över datum. 1 rad för varje månad för år 2017. Vi skapar en @startDate
som ankare och @endDate
som terminator. Vi ställer in dessa på 12 månaders mellanrum, eftersom vi vill ha ett enda år. Sedan kommer rekursionen att lägga till en månad via DATEADD
funktion till @startDate
tills terminatorn är uppfylld i WHERE
klausul. Vi vet att det kommer att ta 11 rekursioner för att nå 12 månader... det vill säga 11 månader + startdatumet. Om vi ställer in MAXRECURSION
till något mindre än 11, då kommer det att misslyckas eftersom 11 behövs för att uppfylla WHERE
klausul i vår rekursiva CTE
, det är terminatorn..
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
För din fråga skulle en enkel sammanfogning räcka.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Jag ser dock att du försöker returnera detta i ett udda format, som bör hanteras i vilket rapporteringsprogram du än använder. Detta skulle få dig nära utan rekursioner.
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