तिथियों का उपयोग करके यहां एक बेहतर उदाहरण दिया गया है। मान लें कि हम तिथियों की एक तालिका बनाना चाहते हैं। वर्ष 2017 के लिए प्रत्येक माह के लिए 1 पंक्ति। हम एक @startDate
. बनाते हैं एंकर और @endDate
. के रूप में टर्मिनेटर के रूप में। हमने इन्हें 12 महीनों के लिए अलग रखा है, क्योंकि हम एक साल चाहते हैं। फिर, रिकर्सन DATEADD
. के माध्यम से एक महीना जोड़ देगा @startDate
. पर कार्य करें टर्मिनेटर WHERE
. में मिलने तक खंड। हम जानते हैं कि 12 महीने हिट होने में 11 पुनरावर्तन लगेंगे... यानी, 11 महीने + प्रारंभ तिथि। अगर हम MAXRECURSION
. सेट करते हैं 11 से कम के लिए, तो यह विफल हो जाएगा क्योंकि WHERE
. को पूरा करने के लिए 11 की आवश्यकता होती है हमारे पुनरावर्ती CTE
में खंड , वह टर्मिनेटर है..
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
आपकी क्वेरी के लिए, एक साधारण जुड़ाव पर्याप्त होगा।
select
firstName
,lastName
,orderDate
,productID
from
customers c
inner join
orders o on o.customerID = c.id
हालांकि, मैं देख रहा हूं कि आप इसे एक अजीब प्रारूप में वापस करने की कोशिश कर रहे हैं, जिसे आप जिस भी रिपोर्टिंग एप्लिकेशन का उपयोग कर रहे हैं उसे संभाला जाना चाहिए। यह आपको बिना रिकर्सन के करीब ले जाएगा।
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