यह काम करता है:
SELECT *
FROM element
WHERE (pk1, pk2, pk3) IN (SELECT (unnest(elements)).*
FROM collection
WHERE id = 1);
या अधिक वर्बोज़, लेकिन बेहतर :
SELECT *
FROM element
WHERE (pk1, pk2, pk3) IN (SELECT (e).*
FROM collection c, unnest(c.elements) e
WHERE c.id = 1);
अधिक मजबूत और unnest()
का मूल्यांकन करने से बचता है कई बार। देखें:
यह भी काम करता है:
SELECT *
FROM element
WHERE ROW((pk1, pk2, pk3)) IN (SELECT unnest(elements)
FROM collection
WHERE id = 1);
समस्या की जड़ यह है कि IN
एक सबक्वेरी लेना दो अलग-अलग रूपों को जानता है। मैनुअल:
का हवाला देते हुए
आपकी असफल क्वेरी दूसरे रूप में हल करता है, जबकि आप (समझदारी से) पहले की अपेक्षा करते हैं। लेकिन दूसरा रूप यह करता है:
मेरी पहली और दूसरी क्वेरी इसे पंक्ति प्रकार को विघटित करके
काम करें। ऑपरेटर के दाईं ओर। तो Postgres में तीन bigint
हैं मान बाएँ और दाएँ और संतुष्ट हैं।
मेरी तीसरी क्वेरी यह पंक्ति प्रकार को दूसरे पंक्ति निर्माता . पोस्टग्रेज केवल पहले स्तर को विघटित करता है और एक एकल समग्र प्रकार के साथ समाप्त होता है - एकल समग्र प्रकार से दाईं ओर मेल खाता है।
ध्यान दें कि कीवर्ड ROW
हम जिस एकल क्षेत्र को लपेट रहे हैं, उसके लिए आवश्यक है। मैनुअल:
आपकी कार्यशील क्वेरी सूक्ष्म रूप से भिन्न है क्योंकि यह एक सूची . प्रदान करता है सबक्वायरी . के बजाय दाईं ओर के मानों का (सेट ) यह एक अलग कोड पथ लेने वाला एक अलग कार्यान्वयन है। इसे मैनुअल में अलग अध्याय भी मिलता है . बाईं ओर ROW कंस्ट्रक्टर के लिए इस प्रकार का कोई विशेष उपचार नहीं है। तो यह अपेक्षा के अनुरूप काम करता है (आपके द्वारा)।
= ANY
. के साथ अधिक समकक्ष (कार्यशील) सिंटैक्स वेरिएंट :
SELECT * FROM element
WHERE (pk1, pk2, pk3) = ANY ('{"(1,2,3)","(2,3,4)"}'::element_pk_t[]);
SELECT * FROM element
WHERE (pk1, pk2, pk3) = ANY (ARRAY[(1,2,3)::element_pk_t,(2,3,4)::element_pk_t]);
SELECT * FROM element
WHERE (pk1, pk2, pk3) = ANY (ARRAY[(1,2,3),(2,3,4)]::element[]);
(pk1, pk2, pk3)::element_pk_t
के साथ भी मान्य या ROW(pk1, pk2, pk3)::element_pk_t
देखें:
चूंकि आपका स्रोत एक सरणी . है , डैनियल की दूसरी क्वेरी (e.pk1, e.pk2, e.pk3) = ANY(c.elements)
के साथ स्वाभाविक रूप से उधार देता है।
लेकिन सबसे तेज़ क्वेरी पर दांव लगाने के लिए , मेरा पैसा मेरे दूसरे संस्करण पर है, क्योंकि मुझे उम्मीद है कि यह पीके इंडेक्स का बेहतर उपयोग करेगा।
अवधारणा के प्रमाण के रूप में। जैसे a_horse ने टिप्पणी की:एक सामान्यीकृत डीबी डिज़ाइन शायद सबसे अच्छा पैमाना होगा।