Voici un meilleur exemple utilisant des dates. Supposons que nous voulions construire une table de dates. 1 ligne pour chaque mois de l'année 2017. Nous créons un @startDate
comme ancre et @endDate
comme terminateur. Nous les avons mis à 12 mois d'intervalle, puisque nous voulons une seule année. Ensuite, la récursivité ajoutera un mois via le DATEADD
fonction à @startDate
jusqu'à ce que le terminateur soit rencontré dans le WHERE
clause. Nous savons qu'il faudra 11 récursions pour atteindre 12 mois... c'est-à-dire 11 mois + la date de début. Si nous définissons le MAXRECURSION
à quelque chose de moins que 11, alors il échouera puisque 11 sont nécessaires pour remplir le WHERE
clause dans notre CTE
récursif , c'est le terminateur..
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
Pour votre requête, une simple jointure suffirait.
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
Cependant, je vois que vous essayez de renvoyer ceci dans un format étrange, qui devrait être géré dans n'importe quelle application de rapport que vous utilisez. Cela vous rapprocherait sans récursivité.
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