मैं एक ओरेकल तालिका में डेटा डेटा करता हूं जो एक ग्राफ के रूप में व्यवस्थित होता है जिसमें चक्र हो सकते हैं (उदाहरण देखें)।गैर-पदानुक्रमित डेटा पर ओरेकल पदानुक्रमित क्वेरी
CREATE TABLE T (parent INTEGER, child INTEGER)
AS select 1 parent, 2 child from dual
union all select 1 parent, 8 child from dual
union all select 2 parent, 3 child from dual
union all select 2 parent, 4 child from dual
union all select 2 parent, 8 child from dual
union all select 3 parent, 4 child from dual
union all select 3 parent, 6 child from dual
union all select 4 parent, 5 child from dual
union all select 5 parent, 8 child from dual
union all select 6 parent, 5 child from dual
union all select 7 parent, 3 child from dual
union all select 7 parent, 5 child from dual
union all select 8 parent, 6 child from dual
मेरा लक्ष्य सभी नोड्स उस नोड एक्स के वंशज (बच्चों, बच्चों के बच्चों, आदि) प्राप्त करने के लिए मान लीजिए कि 2 करते है। मेरे अपेक्षित परिणाम तो है: 3, 4, 5, 6, 8
मुझे पता है कि मैं इस तरह एक प्रश्न डिजाइन कर सकते हैं:
SELECT child, sys_connect_by_path(child,'/')
FROM T
START WITH parent = 2
CONNECT BY NOCYCLE PRIOR child = PARENT;
इस तरह के एक प्रश्न के साथ समस्या यह है इसके माध्यम से जाना होगा कि जब तक वे चक्र नहीं करते हैं, तब तक सभी संभावित पथ, और मेरे वास्तविक डेटा में उनमें से बहुत से तरीके हैं। परिणाम में कई डुप्लिकेट होते हैं - यहां यह है:
child | sys_connect_by_path (for information)
3 | /3
4 | /3/4
5 | /3/4/5
8 | /3/4/5/8
6 | /3/4/5/8/6
6 | /3/6
5 | /3/6/5
8 | /3/6/5/8
4 | /4
5 | /4/5
8 | /4/5/8
6 | /4/5/8/6
8 | /8
6 | /8/6
5 | /8/6/5
मेरा वास्तविक डेटा अधिक जटिल है। ऐसी क्वेरी के निष्पादन की लागत इतनी बड़ी है कि मेरा टीईएमपी टेबलस्पेस, जो ऑटोएक्स्टेंडेबल था, 10 जीबी (मूल रूप से 500 एमबी) तक पहुंच गया और मेरा डेटाबेस वास्तव में डिस्क पूर्ण होने के कारण टूट गया।
मैं इस तरह क्वेरी डिजाइन करने के लिए करने की कोशिश की (खंड के साथ पुनरावर्ती):
WITH descendants(node) AS
(SELECT 2 node FROM dual
UNION ALL
(
SELECT child
FROM T
INNER JOIN descendants D
ON T.parent = D.node
MINUS SELECT node FROM descendants
)
)
SELECT * FROM descendants
समस्या मैं का सामना है जो:
-
Oracle 10g के साथ
- , इस लागू नहीं है (
ORA-32033: unsupported column aliasing
, और कुछ ग्राहक ओरेकल 9 या 10 का उपयोग करते हैं), - ओरेकल 11 जी के साथ, मुझे
ORA-32041: UNION ALL operation in recursive WITH clause must have only two branches
मिलता है। यदि मैं MINUS क्लॉज को हटा देता हूं तो मुझे चक्र मिलेंगे (ORA-32044: cycle detected while executing recursive WITH query
)।
उन नोड्स को 3, 4, 5, 6, 8 कुशलता से प्राप्त करने के लिए आप मेरे मूल डेटा से कैसे पूछेंगे? पीएल/एसक्यूएल समाधान भी स्वागत है।
धन्यवाद।
यह अच्छा लग रहा है, धन्यवाद। क्या यह वैश्विक अस्थायी तालिका रखने का मामला है? – Benoit
मैं नहीं चाहता कि तालिका वैश्विक हो। कल्पना कीजिए कि क्या हो सकता है अगर दो प्रक्रियाओं ने इसे एक साथ उपयोग करना शुरू किया? (यदि स्रोत तालिका को मध्य-निष्पादन में संशोधित किया गया है, तो यह पहले से ही 'असामान्य' व्यवहार के लिए खुला है। लेकिन अगर आपको आवश्यकता हो तो आप पूरी चीज को लेनदेन में सुरक्षित कर सकते हैं।) – MatBailie
@Dems: जैसा कि आपने कहा था _global अस्थायी table_ के बारे में सिर्फ एक नोट ओरेकल विशेषज्ञ नहीं हैं। ओरेकल चीजों में अलग-अलग हैं: [ओरेकल में अस्थायी तालिका बनाम अस्थायी तालिका के बीच क्या अंतर है?] (Http://stackoverflow.com/q/417764) और [एक अस्थायी तालिका बनाना] (http: // डाउनलोड। oracle.com/docs/cd/E11882_01/server.112/e17120/tables003.htm#ADMIN11633) – user272735