2012-11-24 9 views
11

लेवल द्वारा कनेक्ट का उपयोग करना तालिका पर प्रदर्शन करते समय बहुत सारी पंक्तियां वापस करना प्रतीत होता है। क्या हो रहा है इसके पीछे तर्क क्या है?एक टेबल पर स्तर से कनेक्ट क्यों अतिरिक्त पंक्तियों को वापस करता है?

निम्न तालिका मान लिया जाये:

create table a (id number); 

insert into a values (1); 
insert into a values (2); 
insert into a values (3); 

इस क्वेरी 12 पंक्तियों रिटर्न (SQL Fiddle)। स्तंभ LVL तालिका एक में किया जा रहा 1 और तीन प्रत्येक के लिए के मूल्य के साथ तालिका एक में से प्रत्येक के लिए

select id, level as lvl 
    from a 
connect by level <= 2 
    order by id, level 

एक पंक्ति जहां स्तंभ LVL, 2 है अर्थात्:

 
ID | LVL 
---+----- 
1 | 1 
1 | 2 
1 | 2 
1 | 2 
2 | 1 
2 | 2 
2 | 2 
2 | 2 
3 | 1 
3 | 2 
3 | 2 
3 | 2 

यह इस के बराबर है क्वेरी, जो एक ही परिणाम देता है।

select id, level as lvl 
    from dual 
    cross join a 
connect by level <= 2 
    order by id, level 

मुझे समझ नहीं आता क्यों इन प्रश्नों 12 पंक्तियों को वापस या क्यों तीन पंक्तियों जहां LVL 2 और केवल एक ही जहां LVL आईडी स्तंभ के प्रत्येक मूल्य के लिए 1 है देखते हैं है।

आईडी के प्रत्येक मान के लिए 3 returns 13 rows पर "कनेक्ट" स्तरों की संख्या में वृद्धि। 1 जहां एलवीएल 1, 3 है जहां एलवीएल 2 और 9 है जहां एलवीएल 3 है। ऐसा लगता है कि पंक्तियों में पंक्तियों की संख्या एलवीएल माइनस के मूल्य की शक्ति के लिए है।

I हालांकि यह है कि इन प्रश्नों निम्नलिखित है, जो 6 पंक्तियों

select id, lvl 
    from (select level as lvl 
      from dual 
     connect by level <= 2 
       ) 
cross join a 
order by id, lvl 

documentation विशेष रूप से स्पष्ट नहीं है, रिटर्न मेरे लिए, समझा क्या घटित होता है तो में के रूप में ही किया जाएगा होगा। इन शक्तियों के साथ क्या हो रहा है और पहले दो प्रश्न तीसरे के समान क्यों नहीं हैं?

+0

हम MySQL 5 में कुछ, इस के बराबर है? – abhijitcaps

उत्तर

9

पहली क्वेरी में, आप केवल स्तर से कनेक्ट होते हैं। तो यदि स्तर < = 1, तो आप प्रत्येक रिकॉर्ड 1 बार प्राप्त करते हैं। यदि स्तर < = 2 है, तो आपको प्रत्येक स्तर 1 बार (स्तर 1 के लिए) + एन बार मिलता है (जहां एन तालिका में रिकॉर्ड्स की संख्या है)।यह है की तरह आप में शामिल होने के पार कर रहे हैं, क्योंकि आप बस सभी रिकॉर्ड मेज से जब तक स्तर पर पहुंच गया है, तो ले रहे हैं परिणाम सीमित करने के लिए अन्य शर्तों के बिना। स्तर < = 3 के लिए, यह उन परिणामों में से प्रत्येक के लिए फिर से किया जाता है।

तो 3 रिकॉर्ड के लिए:

  • Lvl 1: 3 रिकॉर्ड (सभी होने स्तर 1)
  • Lvl 2: 3 रिकॉर्ड होने स्तर 1 + 3 * 3 रिकॉर्ड होने स्तर 2 = 12
  • एलवीएल 3: 3 + 3 * 3 + 3 * 3 * 3 = 3 9 (वास्तव में, 13 प्रत्येक रिकॉर्ड)।
  • Lvl 4: एक पैटर्न को देखने के लिए शुरू कर रहा? :)

यह वास्तव में एक क्रॉस में शामिल नहीं है। एक क्रॉस में शामिल होने के केवल उन रिकॉर्ड है कि इस क्वेरी परिणाम में स्तर 2 वापसी होगी, जबकि साथ इस से कनेक्ट करते हैं, आप स्तर 1 होने के रिकॉर्ड के साथ ही रिकॉर्ड स्तर 2 होने मिलता है, इस प्रकार के बजाय सिर्फ 3 + 3 * 3 में जिसके परिणामस्वरूप 3 * 3 रिकॉर्ड।

1

आप दूसरों को अंतिम क्वेरी की तुलना करते समय संतरे से सेब की तुलना कर रहे हैं क्योंकि LEVEL को 1-पंक्ति दोहरी तालिका में अलग किया गया है।

select id, level as lvl 
    from a 
connect by level <= 2 
    order by id, level 

कि क्या है कह रहा है, टेबल सेट के साथ शुरू करते हैं (एक से * का चयन करें):

इस क्वेरी पर विचार कर सकते हैं। फिर, प्रत्येक पंक्ति के लिए इस पंक्ति को पूर्व पंक्ति से कनेक्ट करें। चूंकि आपने कनेक्ट में शामिल होने को परिभाषित नहीं किया है, यह वास्तव में एक कार्टेशियन शामिल है, इसलिए जब आपके पास 3 पंक्तियां (1,2,3) 1 2, 1-> 3, 2-> 1, 2 में शामिल हों -> 3, 3-> 1 और 3-> 2 और वे स्वयं भी 1-> 1,2-> 2 और 3-> 3 में शामिल हो जाते हैं। ये जुड़ने स्तर = 2 हैं। इसलिए हमारे पास 9 शामिल हैं, यही कारण है कि आपको 12 पंक्तियां मिलती हैं (3 मूल "स्तर 1" पंक्तियां और कार्टेशियन सेट)।

तो पंक्तियों उत्पादन की संख्या = rowcount + (rowcount^2)

पिछले क्वेरी आप इस

select level as lvl 
      from dual 
     connect by level <= 2 

जो निश्चित रूप से 2 पंक्तियाँ रिटर्न के स्तर को अलग कर रहे हैं में

। इसके बाद आउटपुट के रूप में 6 पंक्तियां देकर, मूल 3 पंक्तियों के लिए कार्टेशियन किया जाता है।

11

connect bystart with क्लॉज और prior ऑपरेटर के बिना प्रयोग किया जाता है, माता-पिता पंक्ति में बच्चों की पंक्ति में शामिल होने पर कोई प्रतिबंध नहीं है। और ओरेकल इस स्थिति में क्या करता है, यह उच्च स्तर की प्रत्येक पंक्ति में पंक्ति को जोड़कर सभी संभावित पदानुक्रम क्रमपरिवर्तन देता है।

SQL> select b 
    2  , level as lvl 
    3  , sys_connect_by_path(b, '->') as ph 
    4  from a 
    5 connect by level <= 2 
    6 ; 

     B  LVL PH 
     ---------- ---------- 
     1   1 ->1 
     1   2 ->1->1 
     2   2 ->1->2 
     3   2 ->1->3 
     2   1 ->2 
     1   2 ->2->1 
     2   2 ->2->2 
     3   2 ->2->3 
     3   1 ->3 
     1   2 ->3->1 
     2   2 ->3->2 
     3   2 ->3->3 

12 rows selected 
+2

'sys_connect_by_path()' <- इस कीवर्ड सब कुछ समझाया। इस सवाल पर सबसे अच्छा जवाब में से एक (न केवल इस विषय में)। – RIKI

0

इस समस्या को दूर करने के लिए नीचे दिए गए तकनीक का उपयोग कर सकते हैं:

select id, level as lvl 
    from a 
     left outer join (select level l from dual connect by level <= 2) lev on 1 = 1 
order by id 
संबंधित मुद्दे

 संबंधित मुद्दे