जब उप-क्वेरी का उपयोग किया जाता है तो त्रुटि [कॉलम को GROUP BY क्लॉज में दिखाई देना चाहिए या एक समग्र फ़ंक्शन में उपयोग किया जाना चाहिए]


17

मेरे पास दो टेबल employeeऔर हैं phones। एक कर्मचारी के पास 0 से n फ़ोन नंबर हो सकते हैं। मैं कर्मचारी नामों को उनके फोन नंबरों के साथ सूचीबद्ध करना चाहता हूं। मैं नीचे क्वेरी का उपयोग कर रहा हूं जो ठीक चलता है।

SELECT empname,array_agg(phonenumber) AS phonenumbers 
FROM employee LEFT OUTER JOIN phones ON employee.empid = phones.empid
GROUP BY employee.empid

यहाँ छवि विवरण दर्ज करें

कर्मचारी तालिका में बड़ी संख्या में पंक्तियाँ हो सकती हैं। मैं एक बार में केवल कुछ कर्मचारियों को लाना चाहता हूं। उदाहरण के लिए मैं अपने फोन नंबरों के साथ 3 कर्मचारियों को लाना चाहता हूं। मैं इस क्वेरी को चलाने का प्रयास कर रहा हूं।

SELECT empname,array_agg(phonenumber) AS phonenumbers 
FROM 
(SELECT * FROM employee ORDER BY empname LIMIT 3 OFFSET 0) AS employee 
LEFT OUTER JOIN phones ON employee.empid = phones.empid
GROUP BY employee.empid

लेकिन मुझे यह त्रुटि मिलती है। ERROR: column "employee.empname" must appear in the GROUP BY clause or be used in an aggregate function दो प्रश्नों के बीच एकमात्र अंतर यह है कि मैं शामिल होने से पहले पंक्तियों को सीमित करने के लिए उत्तरार्द्ध में उप क्वेरी का उपयोग कर रहा हूं। मैं इस त्रुटि को कैसे हल करूं?

जवाबों:


21

Postgres की सुविधा तालिका की प्राथमिक कुंजी का उपयोग करने में सक्षम होने के साथ GROUP BY- साथ GROUP BYखंड में उस तालिका के अन्य स्तंभों को जोड़ने की आवश्यकता नहीं है, अपेक्षाकृत नया है और केवल बेस टेबल के लिए काम करता है। आशावादी (अभी तक?) विचारों, ctes या व्युत्पन्न तालिकाओं (आपके मामले में) के लिए प्राथमिक कुंजी की पहचान करने के लिए पर्याप्त चतुर नहीं है।

आप क्लॉज SELECTमें अपने इच्छित कॉलम जोड़ सकते हैं GROUP BY:

SELECT e.empname, array_agg(p.phonenumber) AS phonenumbers 
FROM 
(SELECT * FROM employee ORDER BY empname LIMIT 3 OFFSET 0) AS e 
LEFT OUTER JOIN phones AS p ON e.empid = p.empid
GROUP BY e.empid, e.empname 
ORDER BY e.empname ;

या एक सबक्वेरी का उपयोग करें (और GROUP BYवहां स्थानांतरण करें ):

SELECT e.empname,
       (SELECT array_agg(p.phonenumber) 
        FROM phones AS p
        WHERE e.empid = p.empid
       ) AS phonenumbers 
FROM 
(SELECT * FROM employee ORDER BY empname LIMIT 3 OFFSET 0) AS e 
ORDER BY e.empname ;

जो भी लिखा जा सकता है:

SELECT e.empname,
       (SELECT array_agg(p.phonenumber) 
        FROM phones AS p
        WHERE e.empid = p.empid
       ) AS phonenumbers 
FROM employee AS e
ORDER BY e.empname LIMIT 3 OFFSET 0 ;

चूंकि आप संस्करण 9.3+ में हैं। तुम भी एक का उपयोग कर सकते हैं LATERAL:

SELECT e.empname,
       p.phonenumbers 
FROM 
   (SELECT * FROM employee ORDER BY empname LIMIT 3 OFFSET 0) AS e
LEFT JOIN LATERAL
   (SELECT array_agg(phonenumber) AS phonenumbers
    FROM phones 
    WHERE e.empid = phones.empid
   ) AS p ON TRUE 
ORDER BY e.empname ;

@ypercude धन्यवाद। यह एक सरल और साफ तरीका है।
प्रोग्रामर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.