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

बाएँ बाहरी कई मानों के साथ सरणी स्तंभ पर शामिल हों

हाँ, ओवरलैप ऑपरेटर && सरणियों पर GIN अनुक्रमणिका का उपयोग कर सकता है . किसी दिए गए व्यक्ति के साथ पंक्तियों को खोजने के लिए यह प्रश्नों के लिए बहुत उपयोगी है (1 ) अभिनेताओं की एक सरणी के बीच:

SELECT * FROM eg_assoc WHERE actors && '{1}'::int[]

हालांकि , आपकी क्वेरी का तर्क दूसरी तरफ है, eg_assoc में सरणियों में सूचीबद्ध सभी व्यक्तियों की तलाश करना . GIN इंडेक्स नहीं है यहाँ मदद करो। हमें बस PK person.id . की btree अनुक्रमणिका चाहिए ।

उचित क्वेरी

मूल बातें:

निम्नलिखित क्वेरी मूल सरणियों को संरक्षित करती हैं बिल्कुल दिए गए अनुसार , संभावित डुप्लिकेट तत्वों और तत्वों के मूल क्रम सहित। 1-आयामी सरणियों के लिए काम करता है . अतिरिक्त आयामों को एकल आयाम में जोड़ दिया जाता है। कई आयामों को संरक्षित करना अधिक जटिल है (लेकिन पूरी तरह से संभव है):

WITH ORDINALITY पोस्टग्रेज 9.4 या बाद के संस्करण में

SELECT aid, actors
     , ARRAY(SELECT name
             FROM   unnest(e.actors) WITH ORDINALITY a(id, i)
             JOIN   eg_person p USING (id)
             ORDER  BY a.i) AS act_names
     , benefactors
     , ARRAY(SELECT name
             FROM   unnest(e.benefactors) WITH ORDINALITY b(id, i)
             JOIN   eg_person USING (id)
             ORDER  BY b.i) AS ben_names
FROM   eg_assoc e;

LATERAL प्रश्न

PostgreSQL के लिए 9.3+

SELECT e.aid, e.actors, a.act_names, e.benefactors, b.ben_names
FROM   eg_assoc e
, LATERAL (
   SELECT ARRAY( SELECT name
                 FROM   generate_subscripts(e.actors, 1) i
                 JOIN   eg_person p ON p.id = e.actors[i]
                 ORDER  BY i)
   ) a(act_names)
, LATERAL (
   SELECT ARRAY( SELECT name
                 FROM   generate_subscripts(e.benefactors, 1) i
                 JOIN   eg_person p ON p.id = e.benefactors[i]
                 ORDER  BY i)
   ) b(ben_names);

db<>fiddle यहां कुछ प्रकारों के साथ।
पुराना sqlfiddle

सूक्ष्म विवरण:यदि कोई व्यक्ति नहीं मिलता है, तो उसे छोड़ दिया जाता है। ये दोनों क्वेरी एक खाली सरणी उत्पन्न करती हैं ('{}' ) यदि संपूर्ण सरणी के लिए कोई व्यक्ति नहीं मिलता है। अन्य क्वेरी शैलियाँ NULL लौटा देंगी . मैंने पहेली में विविधताएं जोड़ीं।

सहसंबंधित सबक्वेरी

पोस्टग्रेज के लिए 8.4+ (जहां generate_subsrcipts() पेश किया गया था):

SELECT aid, actors
     , ARRAY(SELECT name
             FROM   generate_subscripts(e.actors, 1) i
             JOIN   eg_person p ON p.id = e.actors[i]
             ORDER  BY i) AS act_names
     , benefactors
     , ARRAY(SELECT name
             FROM   generate_subscripts(e.benefactors, 1) i
             JOIN   eg_person p ON p.id = e.benefactors[i]
             ORDER  BY i) AS ben_names
FROM   eg_assoc e;

पोस्टग्रेज 9.3 में भी सर्वश्रेष्ठ प्रदर्शन कर सकता है।
ARRAY कंस्ट्रक्टर array_agg() . से तेज़ है . देखें:

आपकी विफल क्वेरी

@a_horse द्वारा प्रदान की गई क्वेरी लगता है काम करने के लिए, लेकिन यह अविश्वसनीय, भ्रामक, संभावित रूप से गलत और अनावश्यक रूप से महंगा है।

  1. दो असंबंधित जुड़ने के कारण प्रॉक्सी क्रॉस जॉइन। एक डरपोक विरोधी पैटर्न। देखें:

    DISTINCT . के साथ सतही रूप से ठीक किया गया में array_agg() उत्पन्न डुप्लिकेट को समाप्त करने के लिए, लेकिन यह वास्तव में एक सुअर पर लिपस्टिक लगा रहा है। यह मूल में डुप्लिकेट को भी हटा देता है क्योंकि इस बिंदु पर अंतर बताना असंभव है - जो संभावित रूप से गलत है।

  2. व्यंजक a_person.id = any(eg_assoc.actors) काम करता है , लेकिन डुप्लिकेट को हटा देता है परिणाम से (इस क्वेरी में दो बार होता है), जो निर्दिष्ट किए जाने तक गलत है।

  3. मूल सरणी तत्वों का क्रम संरक्षित नहीं है . यह सामान्य रूप से मुश्किल है। लेकिन इस सवाल में यह बढ़ गया है, क्योंकि अभिनेता और उपकारक गुणा और फिर से अलग हो जाते हैं, जो गारंटी देता है मनमाना आदेश।

  4. बाहरी SELECT में कोई स्तंभ उपनाम नहीं है डुप्लिकेट कॉलम नामों में परिणाम, जो कुछ क्लाइंट को विफल कर देता है (उपनाम के बिना बेला में काम नहीं कर रहा है)।

  5. min(actors) और min(benefactors) बेकार हैं। आम तौर पर कोई केवल GROUP BY . में कॉलम जोड़ देगा उन्हें नकली-एकत्रित करने के बजाय। लेकिन eg_assoc.aid वैसे भी PK कॉलम है (GROUP BY . में पूरी तालिका को कवर करना) ), तो यह आवश्यक भी नहीं है। बस actors, benefactors

पूरे परिणाम को एकत्रित करना शुरू करने के लिए समय और प्रयास बर्बाद कर रहा है। एक बेहतर क्वेरी का उपयोग करें जो आधार पंक्तियों को गुणा नहीं करती है, फिर आपको उन्हें वापस एकत्रित करने की आवश्यकता नहीं है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डेटाबेस माइग्रेट करने वाली रेल + पोस्टजीआईएस त्रुटियाँ

  2. PostgreSQL धीमा चल रहा है? स्रोत तक पहुंचने के लिए टिप्स और ट्रिक्स

  3. डेटाबेस में किसी इकाई के कई समान गुणों का प्रतिनिधित्व कैसे करें?

  4. जब Django postgresql के साथ क्रमबद्ध लेनदेन अलगाव स्तर का उपयोग कर रहा है तो कौन से विशिष्ट अपवाद क्रमबद्धता विफलता का प्रतिनिधित्व करते हैं?

  5. DISTINCT कॉल के लिए PostgreSQL प्रकार (बिंदु) के लिए कस्टम समानता ऑपरेटर बनाना