2013-01-10 54 views
18

मैं एक master तालिका, जो कई स्तरों, माता-पिता और बच्चे के में संग्रहीत आइटम नहीं है मिल गया है में एक से अधिक टेबल पर मिलती है, और एक दूसरी तालिका जो या अतिरिक्त डेटा नहीं हो सकता है हो सकता है नहीं है। मुझे अपनी मास्टर टेबल से दो स्तरों की पूछताछ करने की आवश्यकता है और मेरी दूसरी तालिका में बाएं शामिल हैं, लेकिन मेरी क्वेरी के भीतर ऑर्डर करने के कारण यह काम नहीं करेगा।एकाधिक बाईं एक क्वेरी

SELECT something FROM master as parent, master as child 
    LEFT JOIN second as parentdata ON parent.secondary_id = parentdata.id 
    LEFT JOIN second as childdata ON child.secondary_id = childdata.id 
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID' 

बाईं में शामिल होने के केवल खंड से में पिछले तालिका के साथ काम करता है, इसलिए मैं केवल यह बाईं मिलती है में से एक के लिए काम करने के लिए कर रहा हूँ। बाएं से कोई भी ऊपर के उदाहरण में मिलती है क्योंकि पहली बाईं खंड से में पहली मेज की ओर अंक में शामिल होने के लिए काम करेंगे, एक दूसरे को इस तरह कभी काम नहीं करेगा।

मैं यह काम कैसे कर सकता हूं?

+6

मिश्रण "पुरानी शैली" "नई शैली" के साथ (बाएं JOIN (FROM खंड में दो तालिका नाम) की तरह कर सकते हैं ...चालू) आँसू में खत्म होने के लिए लगभग निश्चित है। इसे फिर से लिखें, और अपने WHERE खंड पर कड़ी मेहनत करें, जो पंक्तियों को समाप्त कर सकती है जो आप वास्तव में समाप्त नहीं करना चाहते हैं। –

उत्तर

29

क्वेरी इस तरह की काम करना चाहिए - स्पष्ट एएनएसआई JOIN वाक्य रचना के साथ फिर से लिखने के बाद:

SELECT something 
FROM master  parent 
JOIN master  child ON child.parent_id = parent.id 
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id 
LEFT JOIN second childdata ON childdata.id = child.secondary_id 
WHERE parent.parent_id = 'rootID' 

ट्रिपिंग तार है कि यहाँ एक स्पष्ट JOIN से पहले "पुरानी शैली" अल्पविराम के साथ CROSS JOIN (,) बांधता है। I quote the manual here:

किसी भी मामले JOIN में अल्पविराम के FROM -List आइटम को अलग करने की तुलना में अधिक मजबूती से बांधता है।

पहले पुनर्लेखन के बाद, सभी बाएँ से सही से लागू होते हैं मिलती है (तार्किक - Postgres अन्यथा क्वेरी योजना में तालिकाओं को पुनर्व्यवस्थित करने के लिए स्वतंत्र है) और यह काम करता है।

बस मेरी बात करने के लिए, इस काम करेगा, भी:

SELECT something 
FROM master parent 
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id 
,  master child 
LEFT JOIN second childdata ON childdata.id = child.secondary_id 
WHERE child.parent_id = parent.id 
AND parent.parent_id = 'rootID' 

लेकिन स्पष्ट JOIN वाक्य रचना आम तौर पर पसंद किया जाता है, के रूप में अपने मामले एक बार फिर से दिखाता है।

और जागरूक मिलती है जो एक से अधिक (बाएं) पंक्तियों गुणा कर सकते हैं हो सकता है:

2

JOIN बयान भी FROM खंड का हिस्सा हैं, और अधिक औपचारिक रूप से एक join_type लिए किया जाता है एक from_item में दो from_item के गठबंधन, कई जिनमें से एक तो एक अल्पविराम से अलग किए afte फार्म कर सकते हैं FROM आर। http://www.postgresql.org/docs/9.1/static/sql-select.html देखें।

तो आपकी समस्या का सीधा समाधान है: केवल, JOIN के उपयोग करने के लिए के रूप में यह पहले से ही सुझाव दिया गया है

SELECT something 
FROM 
    master as parent LEFT JOIN second as parentdata 
     ON parent.secondary_id = parentdata.id, 
    master as child LEFT JOIN second as childdata 
     ON child.secondary_id = childdata.id 
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID' 

एक बेहतर विकल्प होगा।

4

आप इस

SELECT something 
FROM 
    (a LEFT JOIN b ON a.a_id = b.b_id) LEFT JOIN c on a.a_aid = c.c_id 
WHERE a.parent_id = 'rootID' 
+3

@ डेनिस मेंडर: मुझे नहीं पता कि यह जवाब क्यों स्वीकार किया जाता है। यह पुराने प्रश्न में कुछ नया नहीं जोड़ता है और - कोष्ठक को छोड़कर, जो इस मामले में सिर्फ शोर हैं। और कोई स्पष्टीकरण या तो नहीं। स्पष्ट रूप से डिफ़ॉल्ट रूप से बाएं से दाएं निष्पादित किए जाते हैं (जब तक कि शर्तों में शामिल हों, एक अलग क्रम को मजबूर नहीं करते)। –

+0

@ErwinBrandstetter यह उत्तर अधिक स्पष्ट है, क्योंकि आपके पास टेबल के नाम पर कुछ रिक्त स्थान हैं, और यह भ्रमित है। – kahonmlg

+1

@kahonmlg: किसी भी तालिका नाम में कोई स्थान नहीं है। हो सकता है कि आपने टेबल उपनामों का गलत व्याख्या किया हो। देखें: https://stackoverflow.com/a/11543614/939860 –

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

  • कोई संबंधित समस्या नहीं^_^