Aquí hay un mejor ejemplo usando fechas. Supongamos que queremos construir una tabla de fechas. 1 fila por cada mes del año 2017. Creamos un @startDate
como ancla y @endDate
como terminador. Los establecemos con 12 meses de diferencia, ya que queremos un solo año. Luego, la recursión agregará un mes a través de DATEADD
función al @startDate
hasta que se cumpla el terminador en WHERE
cláusula. Sabemos que se necesitarán 11 recursiones para alcanzar los 12 meses... es decir, 11 meses + la fecha de inicio. Si configuramos el MAXRECURSION
a menos de 11, entonces fallará ya que se necesitan 11 para cumplir con WHERE
cláusula en nuestro recursivo CTE
, ese es el terminador..
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
Para su consulta, bastaría con una simple combinación.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Sin embargo, veo que está tratando de devolver esto en un formato extraño, que debe manejarse en cualquier aplicación de informes que esté utilizando. Esto lo acercaría sin recurrencia.
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