ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 5 · 4లో పాఠం 2కోర్సులో 18/57~10 min
మాడ్యూల్ పాఠాలు (2/4)

స్వీయ-జాయిన్: దానితో పాటు ఒక పట్టిక

కొన్నిసార్లు మీరు ప్రయాణించాలనుకుంటున్న సంబంధం కాదు ఇద్దరి మధ్య ఉంటుంది విభిన్న పట్టికలు, కానీ ఒకే పట్టిక వరుసల మధ్య. సాధారణ ఉదాహరణ: a "వర్గం → ఉపవర్గం" సోపానక్రమం, ఇక్కడ తల్లిదండ్రులు మరియు పిల్లలు ఇద్దరూ వరుసలు అదే 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 చైల్డ్ అనే వరుసలను తీసుకోండి, మరియు ప్రతి ఒక్కరు 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ని అందిస్తుంది, అయితే LEFT JOIN అడ్డు వరుస కారణంగా COUNT(*) 1ని అందిస్తుంది NULL.

మీరే ప్రయత్నించండి

వ్యాయామం#sql.m5.l2.e1
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

ogni sotto-categoria (కేటగిరీ కాన్ పేరెంట్_ఐడి NULL కాదు), మోస్ట్ర ఇల్ నోమ్ డెల్లా సోట్టో-కేటగిరియా మరియు ఇల్ నోమ్ డెల్లా సువా కేటగిరీ-పాడ్రే. కారణంగా కాలన్: ఉపవర్గం, వర్గం. ఆర్డినా పర్ కేటగిరీ పోయి పర్ సబ్ కేటగిరీ.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

La condizione del self-JOIN è child.parent_id = parent.id.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం సమీక్షించండి

వ్యాయామం#sql.m5.l2.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

ప్రతి ogni కేటగిరీ-రాడిస్ (పేరెంట్_ఐడి NULL), మోస్ట్ర ఇల్ నోమ్ మరియు ఇల్ న్యూమెరో డి సోట్టో-కేటగిరీ. డ్యూ కోలోన్: పేరు, పిల్లలు. పేరుకు ఆర్డినా. ఉనా చివరికి రాడిస్ సెంజా ఫిగ్లీ కాన్ 0ని చేర్చండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

ఎడమవైపు రెండుసార్లు కేటగిరీల్లో చేరండి (తల్లిదండ్రుల కోసం అలియాస్ p, పిల్లల కోసం c). పిల్లలు లేకుండా రూట్‌లలో 0ని పొందడానికి COUNT(c.id), COUNT(*)ని కాదు.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది