मुख्य सामग्री पर जाएं
मॉड्यूल 5 · पाठ 2 का 4पाठ्यक्रम में 18/57~10 min
मॉड्यूल पाठ (2/4)

सेल्फ-जॉइन: स्वयं के साथ एक टेबल

कभी-कभी आप जिस रिश्ते से गुज़रना चाहते हैं वह दो के बीच नहीं होता है अलग-अलग तालिकाएँ, लेकिन एक ही तालिका की पंक्तियों के बीच। विशिष्ट उदाहरण: ए "श्रेणी → उपश्रेणी" पदानुक्रम, जहां माता-पिता और बच्चे दोनों की पंक्तियाँ हैं वही categories तालिका, parent_id द्वारा लिंक की गई।

एक पंक्ति (बच्चा) और "उसकी" दूसरी पंक्ति (मूल) को एक साथ पढ़ने के लिए आप a का उपयोग करते हैं स्वयं-जुड़ना: एक ही तालिका FROM में दो बार दिखाई देती है, दो के साथ विभिन्न उपनाम.

वाक्यविन्यास

SQL
SELECT colonne
FROM   tabella AS alias_a
JOIN   tabella AS alias_b ON alias_a.foreign_key = alias_b.id;

उपनाम अनिवार्य है: यदि हम AS a / AS b को छोड़ देते हैं, तो PostgreSQL में कोई नहीं है यह जानने का तरीका कि जब हम name या id लिखते हैं तो हमारा मतलब दोनों प्रतियों में से किससे है।

SQL
-- Ogni sotto-categoria con il nome della categoria padre:
SELECT child.name  AS subcategory,
       parent.name AS category
FROM   categories AS child
JOIN   categories AS parent ON child.parent_id = parent.id;

सादे अंग्रेजी में पढ़ें: "categories की पंक्तियाँ लें जिनका नाम child है, और प्रत्येक के लिए categories की पैरेंट नामक पंक्ति ढूंढें जिसका id है बच्चे का parent_id".

परिणाम में मूल श्रेणियां (parent_id = NULL वाली) शामिल नहीं हैं क्योंकि INNER JOIN बिना मिलान वाली पंक्तियों को छोड़ देता है। अगर आप शामिल करना चाहते हैं उन्हें, LEFT JOIN का उपयोग करें।

"जड़ों को भी बनाए रखने" के लिए LEFT के साथ स्वयं जुड़ें

SQL
-- Tutte le categorie, con nome del padre o NULL se sono radice:
SELECT child.name AS category,
       parent.name AS parent
FROM   categories AS child
LEFT JOIN categories AS parent ON child.parent_id = parent.id;

अब आपको parent = NULL के साथ 9 पंक्तियाँ (डेटासेट में प्रत्येक श्रेणी) मिलती हैं 3 जड़ों के लिए.

स्वयं-जुड़ने के साथ एकत्रीकरण

यह पूछने के लिए GROUP BY के साथ बहुत अच्छी तरह से संयोजित होता है कि "प्रत्येक में कितने बच्चे हैं" माता-पिता के पास है":

SQL
SELECT p.name AS parent_category,
       COUNT(c.id) AS children
FROM   categories AS p
LEFT JOIN categories AS c ON c.parent_id = p.id
WHERE  p.parent_id IS NULL          -- solo le radici
GROUP BY p.name
ORDER BY p.name;

दो महत्वपूर्ण विवरण नोट करें:

  1. WHERE p.parent_id IS NULL जॉइन से पहले फिल्टर: हम केवल लेते हैं जड़ें "बाएं हाथ की मेज" के रूप में।
  2. COUNT(c.id) (COUNT(*) नहीं) बच्चों के बिना जड़ों के लिए 0 लौटाता है, जबकि COUNT(*) LEFT JOIN पंक्ति के कारण 1 लौटाएगा शून्य.

खुद कोशिश करना

व्यायाम#sql.m5.l2.e1
प्रयास: 0लोड हो रहा है...

अन्य श्रेणियों के लिए (पैरेंट_आईडी के साथ श्रेणी, शून्य नहीं), अधिकांश नाम श्रेणी और श्रेणी श्रेणी के हैं। देय स्तम्भ: उपश्रेणी, श्रेणी। प्रति श्रेणी पोई प्रति उपश्रेणी में ऑर्डिना।

संपादक लोड हो रहा है...
संकेत दिखाएँ

सेल्फ-जॉइन कंडीशन एक child.parent_id =parent.id है।

3 प्रयासों के बाद समाधान उपलब्ध है

व्यायाम की समीक्षा करें

व्यायाम#sql.m5.l2.e2
प्रयास: 0लोड हो रहा है...

एक अन्य श्रेणी-मूल (parent_id IS NULL) के लिए, अधिकांश नाम और संख्या-श्रेणी। देय स्तम्भ: नाम, बच्चे। प्रति नाम ऑर्डिना. इसमें यूना इवेंटुअल रेडिस सेन्ज़ा फिग्ली कॉन 0 शामिल है।

संपादक लोड हो रहा है...
संकेत दिखाएँ

श्रेणियों पर दो बार बाएँ शामिल हों (माता-पिता के लिए उपनाम पी, बच्चे के लिए सी)। बच्चों के बिना जड़ों पर 0 प्राप्त करने के लिए COUNT(c.id) का उपयोग करें, COUNT(*) का नहीं।

3 प्रयासों के बाद समाधान उपलब्ध है