यहाँ एक पुनरावर्ती CTE का उपयोग करके एक समाधान दिया गया है। मैंने lvl
. का इस्तेमाल किया level
. के बाद से स्तंभ शीर्षलेख के रूप में Oracle में एक आरक्षित शब्द है। आप शब्दावली में अन्य अंतर भी देखेंगे। मैं तुरंत उच्च स्तर के लिए "माता-पिता" और> =0 चरणों के लिए "पूर्वज" का उपयोग करता हूं (नोड को अपने पूर्वज के रूप में दिखाने की आपकी आवश्यकता को समायोजित करने के लिए)। मैंने ORDER BY
का उपयोग किया है आउटपुट को आपके मेल खाने का कारण बनने के लिए खंड; आपको ऑर्डर की गई पंक्तियों की आवश्यकता हो भी सकती है और नहीं भी।
आपके प्रश्न ने मुझे फिर से पढ़ने के लिए प्रेरित किया, और अधिक विस्तार से, पदानुक्रमित प्रश्नों के बारे में, यह देखने के लिए कि क्या यह पुनरावर्ती सीटीई के बजाय उनके साथ किया जा सकता है। वास्तव में मुझे पहले से ही पता है कि आप CONNECT_BY_PATH
. का उपयोग कर सकते हैं , लेकिन एक substr
. का उपयोग करके उस पर पदानुक्रमित पथ में शीर्ष स्तर को पुनः प्राप्त करने के लिए बिल्कुल भी संतोषजनक नहीं है, एक बेहतर तरीका होना चाहिए। (यदि पदानुक्रमित प्रश्नों के साथ ऐसा करने का यही एकमात्र तरीका था, तो मैं निश्चित रूप से उपलब्ध होने पर पुनरावर्ती सीटीई मार्ग पर जाऊंगा)। अगर मुझे कोई अच्छा समाधान मिल जाए, तो मैं यहां पदानुक्रमित क्वेरी समाधान जोड़ूंगा।
with h ( node, parent ) as (
select 1 , null from dual union all
select 2 , 1 from dual union all
select 3 , 2 from dual
),
r ( node , ancestor, steps ) as (
select node , node , 0
from h
union all
select r.node, h.parent, steps + 1
from h join r
on h.node = r.ancestor
)
select node, ancestor,
1+ (max(steps) over (partition by node)) as lvl, steps
from r
where ancestor is not null
order by lvl, steps desc;
NODE ANCESTOR LVL STEPS
---------- ---------- ---------- ----------
1 1 1 0
2 1 2 1
2 2 2 0
3 1 3 2
3 2 3 1
3 3 3 0
जोड़ा गया :श्रेणीबद्ध क्वेरी समाधान
ठीक है - मिल गया। कृपया दोनों समाधानों का परीक्षण करके देखें कि कौन बेहतर प्रदर्शन करता है; एक अलग सेटअप पर परीक्षणों से, रिकर्सिव सीटीई पदानुक्रमित क्वेरी से काफी तेज था, लेकिन यह विशिष्ट स्थिति पर निर्भर हो सकता है। यह भी:पुनरावर्ती CTE केवल Oracle 11.2 और इसके बाद के संस्करण में काम करता है; पदानुक्रमित समाधान पुराने संस्करणों के साथ काम करता है।
मैंने अनातोली से मिलान करने के लिए थोड़ा और परीक्षण डेटा जोड़ा।
with h ( node, parent ) as (
select 1 , null from dual union all
select 2 , 1 from dual union all
select 3 , 2 from dual union all
select 4 , 2 from dual union all
select 5 , 4 from dual
)
select node,
connect_by_root node as ancestor,
max(level) over (partition by node) as lvl,
level - 1 as steps
from h
connect by parent = prior node
order by node, ancestor;
NODE ANCESTOR LVL STEPS
---------- ---------- ---------- ----------
1 1 1 0
2 1 2 1
2 2 2 0
3 1 3 2
3 2 3 1
3 3 3 0
4 1 3 2
4 2 3 1
4 4 3 0
5 1 4 3
5 2 4 2
5 4 4 1
5 5 4 0