Ecco un esempio migliore usando le date. Supponiamo di voler costruire una tabella di date. 1 riga per ogni mese dell'anno 2017. Creiamo un @startDate
come anchor e @endDate
come terminatore. Abbiamo impostato questi a 12 mesi di distanza, dal momento che vogliamo un solo anno. Quindi, la ricorsione aggiungerà un mese tramite il DATEADD
funzione al @startDate
fino a quando il terminatore non viene soddisfatto in WHERE
clausola. Sappiamo che ci vorranno 11 ricorsioni per raggiungere 12 mesi... cioè 11 mesi + la data di inizio. Se impostiamo il MAXRECURSION
a qualcosa di meno di 11, allora fallirà poiché 11 sono necessari per soddisfare il WHERE
clausola nel nostro CTE
ricorsivo , questo è il terminatore..
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
Per la tua richiesta sarebbe sufficiente un semplice join.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Tuttavia, vedo che stai cercando di restituire questo in un formato strano, che dovrebbe essere gestito in qualsiasi applicazione di segnalazione che stai utilizzando. Questo ti porterebbe vicino senza ricorsione.
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