Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

एक MySQL पदानुक्रमित पुनरावर्ती क्वेरी कैसे बनाएं?

MySQL 8+ के लिए: पुनरावर्ती साथ का उपयोग करें सिंटैक्स।
MySQL 5.x: . के लिए इनलाइन वैरिएबल, पाथ आईडी या सेल्फ़-जॉइन का इस्तेमाल करें.

MySQL 8+

with recursive cte (id, name, parent_id) as (
  select     id,
             name,
             parent_id
  from       products
  where      parent_id = 19
  union all
  select     p.id,
             p.name,
             p.parent_id
  from       products p
  inner join cte
          on p.parent_id = cte.id
)
select * from cte;

parent_id =19 . में निर्दिष्ट मान id . पर सेट होना चाहिए माता-पिता के सभी वंशजों को आप चुनना चाहते हैं।

MySQL 5.x

MySQL संस्करणों के लिए जो सामान्य तालिका अभिव्यक्तियों (संस्करण 5.7 तक) का समर्थन नहीं करते हैं, आप इसे निम्न क्वेरी के साथ प्राप्त करेंगे:

select  id,
        name,
        parent_id 
from    (select * from products
         order by parent_id, id) products_sorted,
        (select @pv := '19') initialisation
where   find_in_set(parent_id, @pv)
and     length(@pv := concat(@pv, ',', id))

यह रहा एक fiddle

यहां, @pv :='19' . में निर्दिष्ट मान id . पर सेट होना चाहिए माता-पिता के सभी वंशजों को आप चुनना चाहते हैं।

यह तब भी काम करेगा जब माता-पिता के पास एकाधिक हो बच्चे। हालांकि, यह आवश्यक है कि प्रत्येक रिकॉर्ड parent_id . शर्त को पूरा करता हो , अन्यथा परिणाम पूर्ण नहीं होंगे।

क्वेरी के अंदर वेरिएबल असाइनमेंट

यह क्वेरी विशिष्ट MySQL सिंटैक्स का उपयोग करती है:इसके निष्पादन के दौरान चर निर्दिष्ट और संशोधित किए जाते हैं। निष्पादन के क्रम के बारे में कुछ धारणाएँ बनाई गई हैं:

  • से खंड का मूल्यांकन पहले किया जाता है। तो वहीं @pv आरंभ हो जाता है।
  • कहां खंड का मूल्यांकन प्रत्येक रिकॉर्ड के लिए से . से पुनर्प्राप्ति के क्रम में किया जाता है उपनाम तो यह वह जगह है जहां एक शर्त केवल उन अभिलेखों को शामिल करने के लिए रखी जाती है जिनके लिए माता-पिता को पहले से ही वंशज पेड़ में होने के रूप में पहचाना गया था (प्राथमिक माता-पिता के सभी वंशज क्रमशः @pv में जोड़े जाते हैं। )।
  • इस कहां में शर्तें खंड का मूल्यांकन क्रम में किया जाता है, और कुल परिणाम निश्चित होने के बाद मूल्यांकन बाधित हो जाता है। इसलिए दूसरी शर्त दूसरे स्थान पर होनी चाहिए, क्योंकि यह id . जोड़ता है मूल सूची में, और यह केवल तभी होना चाहिए जब id पहली शर्त पास करता है। लंबाई फ़ंक्शन को केवल यह सुनिश्चित करने के लिए कहा जाता है कि यह स्थिति हमेशा सत्य है, भले ही pv स्ट्रिंग किसी कारण से एक मिथ्या मान उत्पन्न करेगी।

कुल मिलाकर, किसी को भी इन धारणाओं पर भरोसा करना बहुत जोखिम भरा लग सकता है। दस्तावेज़ीकरण चेतावनी देता है:

<ब्लॉकक्वॉट>

आपको अपेक्षित परिणाम मिल सकते हैं, लेकिन इसकी गारंटी नहीं है [...] उपयोगकर्ता चर वाले भावों के मूल्यांकन का क्रम अपरिभाषित है।

तो भले ही यह उपरोक्त क्वेरी के साथ लगातार काम करता है, मूल्यांकन क्रम अभी भी बदल सकता है, उदाहरण के लिए जब आप शर्तों को जोड़ते हैं या इस क्वेरी को एक बड़ी क्वेरी में एक दृश्य या उप-क्वेरी के रूप में उपयोग करते हैं। यह एक "सुविधा" है जिसे भविष्य में हटा दिया जाएगा MySQL रिलीज़ :

<ब्लॉकक्वॉट>

MySQL की पिछली रिलीज़ ने SET . के अलावा किसी अन्य स्टेटमेंट में उपयोगकर्ता चर के लिए एक मान निर्दिष्ट करना संभव बना दिया है . यह कार्यक्षमता पश्चगामी संगतता के लिए MySQL 8.0 में समर्थित है, लेकिन MySQL के भविष्य के रिलीज में हटाने के अधीन है।

जैसा कि ऊपर बताया गया है, MySQL 8.0 से आगे आपको पुनरावर्ती साथ का उपयोग करना चाहिए वाक्य रचना।

दक्षता

बहुत बड़े डेटा सेट के लिए यह समाधान धीमा हो सकता है, क्योंकि find_in_set किसी सूची में किसी संख्या को खोजने के लिए ऑपरेशन सबसे आदर्श तरीका नहीं है, निश्चित रूप से उस सूची में नहीं जो परिमाण के उसी क्रम में आकार तक पहुँचती है जैसे रिकॉर्ड की संख्या वापस आती है।

वैकल्पिक 1:पुनरावर्ती के साथ , इससे कनेक्ट करें

अधिक से अधिक डेटाबेस SQL:1999 ISO मानक [RECURSIVE] के साथ कार्यान्वित करते हैं। /कोड> वाक्य रचना पुनरावर्ती प्रश्नों के लिए (उदा. पोस्टग्रेस 8.4+ , SQL Server 2005+ , DB2 , Oracle 11gR2+ , SQLite 3.8.4+ , Firebird 2.1+ , H2 , HyperSQL 2.1.0+ , Teradata , MariaDB 10.2.2+ ) और संस्करण 8.0 के अनुसार, MySQL भी इसका समर्थन करता है . सिंटैक्स का उपयोग करने के लिए इस उत्तर का शीर्ष देखें।

कुछ डेटाबेस में पदानुक्रमित लुक-अप के लिए एक वैकल्पिक, गैर-मानक सिंटैक्स होता है, जैसे कनेक्ट बाय खंड Oracle पर उपलब्ध है , DB2 , Informix , CUBRID और अन्य डेटाबेस।

MySQL संस्करण 5.7 ऐसी सुविधा प्रदान नहीं करता है। जब आपका डेटाबेस इंजन यह सिंटैक्स प्रदान करता है या आप किसी एक में माइग्रेट कर सकते हैं, तो यह निश्चित रूप से जाने का सबसे अच्छा विकल्प है। यदि नहीं, तो निम्नलिखित विकल्पों पर भी विचार करें।

वैकल्पिक 2:पथ-शैली पहचानकर्ता

अगर आप id असाइन करेंगे तो चीज़ें बहुत आसान हो जाती हैं मान जिनमें पदानुक्रमित जानकारी होती है:एक पथ। उदाहरण के लिए, आपके मामले में यह ऐसा दिखाई दे सकता है:

<थ>नाम
आईडी
19 श्रेणी1
19/1 श्रेणी2
19/1/1 श्रेणी3
19/1/1/1 श्रेणी4

फिर आपका चुनें इस तरह दिखेगा:

select  id,
        name 
from    products
where   id like '19/%'

वैकल्पिक 3:बार-बार सेल्फ़-जॉइन करना

यदि आप एक ऊपरी सीमा जानते हैं कि आपका पदानुक्रम वृक्ष कितना गहरा हो सकता है, तो आप एक मानक sql . का उपयोग कर सकते हैं इस तरह की क्वेरी:

select      p6.parent_id as parent6_id,
            p5.parent_id as parent5_id,
            p4.parent_id as parent4_id,
            p3.parent_id as parent3_id,
            p2.parent_id as parent2_id,
            p1.parent_id as parent_id,
            p1.id as product_id,
            p1.name
from        products p1
left join   products p2 on p2.id = p1.parent_id 
left join   products p3 on p3.id = p2.parent_id 
left join   products p4 on p4.id = p3.parent_id  
left join   products p5 on p5.id = p4.parent_id  
left join   products p6 on p6.id = p5.parent_id
where       19 in (p1.parent_id, 
                   p2.parent_id, 
                   p3.parent_id, 
                   p4.parent_id, 
                   p5.parent_id, 
                   p6.parent_id) 
order       by 1, 2, 3, 4, 5, 6, 7;

इसे देखें fiddle

कहां स्थिति निर्दिष्ट करती है कि आप किस माता-पिता के वंशजों को पुनः प्राप्त करना चाहते हैं। आप इस क्वेरी को आवश्यकतानुसार अधिक स्तरों के साथ बढ़ा सकते हैं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL प्रदर्शन:SQL में शामिल होने का परिचय

  2. मैं MySQL डेटाबेस में डेटा कैसे सम्मिलित कर सकता हूँ?

  3. रिलेशनल डेटाबेस मैनेजमेंट सिस्टम (RDBMS):MSSQL बनाम MySQL

  4. मैसकल कवरिंग बनाम कंपोजिट बनाम कॉलम इंडेक्स

  5. mysql तालिका पंक्तियों को कॉलम में कैसे स्थानांतरित करें

© कॉपीराइट http://hi.sqldat.com सर्वाधिकार सुरक्षित