Hier ist ein besseres Beispiel mit Datumsangaben. Angenommen, wir möchten eine Datumstabelle erstellen. 1 Zeile für jeden Monat für das Jahr 2017. Wir erstellen ein @startDate
als Anker und @endDate
als Terminator. Wir legen diese auf 12 Monate auseinander, da wir ein einzelnes Jahr wollen. Dann fügt die Rekursion über DATEADD
einen Monat hinzu Funktion zum @startDate
bis das Abschlusszeichen im WHERE
getroffen wird Klausel. Wir wissen, dass es 11 Rekursionen braucht, um 12 Monate zu erreichen ... also 11 Monate + das Startdatum. Wenn wir MAXRECURSION
setzen zu etwas weniger als 11, dann schlägt es fehl, da 11 benötigt werden, um WHERE
zu erfüllen -Klausel in unserem rekursiven CTE
, das ist der 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
Für Ihre Anfrage würde ein einfacher Join ausreichen.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Ich sehe jedoch, dass Sie versuchen, dies in einem seltsamen Format zurückzugeben, das in jeder Berichtsanwendung verarbeitet werden sollte, die Sie verwenden. Dies würde Sie ohne Rekursion nahe bringen.
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