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

बाएं जॉइन के साथ क्वेरी 0 की गिनती के लिए पंक्तियों को वापस नहीं कर रही है

LEFT JOIN को ठीक करें

यह काम करना चाहिए:

SELECT o.name AS organisation_name, count(e.id) AS total_used
FROM   organisations   o
LEFT   JOIN exam_items e ON e.organisation_id = o.id 
                        AND e.item_template_id = #{sanitize(item_template_id)}
                        AND e.used
GROUP  BY o.name
ORDER  BY o.name;

आपके पास एक LEFT [OUTER] JOIN . था लेकिन बाद में WHERE शर्तों ने इसे एक सादे [INNER] JOIN . की तरह काम करने के लिए बनाया है .
शर्तों को JOIN . पर ले जाएं इसे इरादा के अनुसार काम करने के लिए खंड। इस तरह, केवल इन सभी शर्तों को पूरा करने वाली पंक्तियों को पहले स्थान पर जोड़ा जाता है (या दाएं से कॉलम) तालिका NULL से भरी हुई है)। जैसा कि आपके पास था, सम्मिलित पंक्तियों का वस्तुतः बाद . अतिरिक्त स्थितियों के लिए परीक्षण किया जाता है LEFT JOIN और अगर वे पास नहीं होते हैं तो उन्हें हटा दिया जाता है, ठीक वैसे ही जैसे एक सादे JOIN

count() शुरू करने के लिए कभी भी NULL नहीं लौटाता। यह इस संबंध में कुल कार्यों के बीच एक अपवाद है। इसलिए, <स्ट्राइक>COALESCE(COUNT(col)) कभी नहीं अतिरिक्त मापदंडों के साथ भी समझ में आता है। मैनुअल:

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

यह ध्यान दिया जाना चाहिए कि count को छोड़कर , जब कोई पंक्ति नहीं चुनी जाती है तो ये फ़ंक्शन एक शून्य मान लौटाते हैं।

बोल्ड जोर मेरा। देखें:

  • उन विशेषताओं की संख्या गिनें जो एक पंक्ति के लिए NULL हैं

count() परिभाषित कॉलम पर होना चाहिए NOT NULL (जैसे e.id ), या जहां शामिल होने की स्थिति गारंटी देती है NOT NULL (e.organisation_id , e.item_template_id , या e.used ) उदाहरण में।

चूंकि used टाइप है boolean , व्यंजक e.used = true शोर है जो केवल e.used . तक जल जाता है ।

चूंकि o.name परिभाषित नहीं है UNIQUE NOT NULL , आप GROUP BY o.id . करना चाह सकते हैं इसके बजाय (id पीके होने के नाते) - जब तक आप इरादा पंक्तियों को एक ही नाम (NULL सहित) से मोड़ने के लिए।

पहले एकत्र करें, बाद में शामिल हों

यदि exam_items . की अधिकांश या सभी पंक्तियाँ प्रक्रिया में गिना जाता है, यह समकक्ष क्वेरी आमतौर पर काफी तेज/सस्ता होती है:

SELECT o.id, o.name AS organisation_name, e.total_used
FROM   organisations o
LEFT   JOIN (
   SELECT organisation_id AS id   -- alias to simplify join syntax
        , count(*) AS total_used  -- count(*) = fastest to count all
   FROM   exam_items
   WHERE  item_template_id = #{sanitize(item_template_id)}
   AND    used
   GROUP  BY 1
   ) e USING (id)
ORDER  BY o.name, o.id;

(यह माना जा रहा है कि आप पंक्तियों को उसी नाम से मोड़ना नहीं चाहते हैं जैसा कि ऊपर बताया गया है - सामान्य मामला।)

अब हम तेज़ / सरल count(*) . का उपयोग कर सकते हैं सबक्वेरी में, और हमें GROUP BY . की आवश्यकता नहीं है बाहरी में SELECT

देखें:

  • एक ही क्वेरी में कई array_agg() कॉल


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. GroupingError:ERROR:कॉलम ग्रुप बाय क्लॉज में दिखाई देना चाहिए या एक समग्र फ़ंक्शन में उपयोग किया जाना चाहिए

  2. Django ORM में क्वेरी द्वारा समूहीकृत पर एक एनोटेट फ़ील्ड के अधिकतम योग की गणना करें?

  3. रेल + पोस्टग्रेज ड्रॉप त्रुटि:डेटाबेस को अन्य उपयोगकर्ताओं द्वारा एक्सेस किया जा रहा है

  4. Psycopg2 / Python DB-API और PostgreSQL के साथ पैरामीटरयुक्त प्रश्न

  5. PostgreSQL में डेटाबेस तक पहुंच कैसे सीमित करें