सरणी में पोस्टग्रेट्स नहीं


96

मैं Postgres के मूल सरणी प्रकार का उपयोग कर रहा हूं, और उन अभिलेखों को खोजने की कोशिश कर रहा हूं जहां आईडी सरणी प्राप्तकर्ता आईडी में नहीं है।

मैं पा सकता हूँ कि वे कहाँ हैं:

SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))

लेकिन यह काम नहीं करता है:

SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3  = NOT ANY (recipient_ids))

इस स्थिति के लिए परीक्षण करने का सही तरीका क्या है?


WHERE 3 NOT IN recipient_idsकाम करता है ?
Janus Troelsen

1
संबंधित नोट: के रूप में text[]और int[]सरणी के लिए:select not(array[1,2,3] @> array[3]);
स्टीव पीक

3
प्रो टिप: यदि आप जाँच रहे हैं कि कोई nullकॉलम किसी सरणी में समाहित है या नहीं, तो यह हमेशा कहेगा कि नहीं। यह मुझे 20 मिनट के डिबगिंग जैसे कई युक्त तरीकों से इस निष्कर्ष पर आया कि आप जाँच नहीं कर सकते हैं कि अशक्त एक सरणी में समाहित है या नहीं
आंद्रे पेना

जवाबों:


136
SELECT COUNT(*) FROM "messages" WHERE NOT (3 = ANY (recipient_ids))

आप हमेशा के WHERE (condition)साथ नकारात्मक कर सकते हैंWHERE NOT (condition)


2
@aschyiel - आप अपनी इनपुट सूची बढ़ने के ANYबजाय वापस स्विच करना चाहते हैं : stackoverflow.com/questions/1009706/…INrecipient_ids
derekm

39

आप इसे थोड़ा घुमा सकते हैं और कह सकते हैं "3 सभी आईडी के बराबर नहीं है":

where 3 != all (recipient_ids)

से ठीक मैनुअल :

9.21.4। सभी (सरणी)

expression operator ALL (array expression)

दाहिने हाथ की ओर एक कोष्ठक अभिव्यक्ति है, जिसे एक सरणी मान प्राप्त करना चाहिए। बाएं हाथ की अभिव्यक्ति का मूल्यांकन किया गया है और दिए गए ऑपरेटर का उपयोग करके सरणी के प्रत्येक तत्व की तुलना में , जिसे बूलियन परिणाम प्राप्त करना होगा। ALLयदि सभी तुलनाओं का परिणाम सही है (मामले में जहां सरणी में शून्य तत्व हैं) सहित "सच" का परिणाम है। यदि कोई गलत परिणाम मिलता है तो परिणाम "गलत" है।


यह वास्तव में यह नहीं समझाता है कि anyइस मामले में काम क्यों नहीं करता है
seanlinsley

इसे स्वीकार किया जाना चाहिए क्योंकि यह कारण को ठीक से समझाता है। पुनश्च आप पा सकते हैं anyऔर allडाक डॉक पर, जो कहता है: " x <> ANY (a,b,c) के बराबर है x <> a OR <> b OR x <> c"। रेफरी: postgresqltutorial.com/postgresql-any postgresqltutorial.com/postgresql-all
टायलर टेम्प

19

बढ़ाने ALL/ANYजवाब

मैं उन सभी समाधानों को पसंद करता हूं जो अतिरिक्त नोट्स (जैसे NULL s के लिए) की सराहना करते हुए उपयोग करते हैं allया anyपरिणाम प्राप्त करते हैं । एक और आश्रय के रूप में, यहाँ उन ऑपरेटरों के बारे में सोचने का एक तरीका है।

आप उनके बारे में शॉर्ट-सर्किट ऑपरेटरों के रूप में सोच सकते हैं :

  • all(array)सरणी में सभी मानों के माध्यम से जाता है, प्रत्येक को दिए गए ऑपरेटर का उपयोग करके संदर्भ मान से तुलना करता है। जैसे ही तुलना की जाती है false, प्रक्रिया झूठी, अन्यथा सच होती है। (शॉर्ट-सर्किट तार्किक के लिए तुलनीय and।)
  • any(array)सरणी में सभी मानों के माध्यम से जाता है, प्रत्येक को दिए गए ऑपरेटर का उपयोग करके संदर्भ मान से तुलना करता है। जैसे ही तुलना की जाती है true, प्रक्रिया सच के साथ समाप्त होती है, अन्यथा झूठ। (शॉर्ट-सर्किट तार्किक के लिए तुलनीय or।)

यही कारण है कि 3 <> any('{1,2,3}')वांछित परिणाम नहीं मिलता है: प्रक्रिया असमानता के लिए 1 के साथ 3 की तुलना करती है, जो सच है, और तुरंत सच हो जाता है। 3 से भिन्न सरणी में एक एकल मान पूरी स्थिति को सत्य बनाने के लिए पर्याप्त है। अंतिम सरणी स्थिति में 3 संभावित है। कभी प्रयोग नहीं हुआ।

3 <> all('{1,2,3}')दूसरी ओर यह सुनिश्चित करता है कि सभी मूल्य समान नहीं हैं। 3. यह सभी तुलनाओं के माध्यम से चलेगा, जो एक ऐसे तत्व तक सही है, जो समग्र परिणाम के रूप में झूठे (इस मामले में अंतिम) प्राप्त करता है। यही ओपी चाहता है।



11

ताज़ा जानकारी:

पोस्ट के अनुसार 9.3,

आप इसे प्राप्त करने के लिए (ऑपरेटर शामिल) केNOT साथ मिलकर उपयोग कर सकते हैं ।@>

अर्थात।

SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids @> ARRAY[3];


11

NULLs से सावधान रहें

दोनों ALL:

(some_value != ALL(some_array))

और ANY:

NOT (some_value = ANY(some_array))

जब तक some_arrayअशक्त नहीं है तब तक काम करेंगे । यदि सरणी अशक्त हो सकती है, तो आपको इसके लिए coalesce (), उदाहरण के लिए खाता होना चाहिए

(some_value != ALL(coalesce(some_array, array[]::int[])))

या

NOT (some_value = ANY(coalesce(some_array, array[]::int[])))

से डॉक्स :

यदि सरणी अभिव्यक्ति एक अशक्त सरणी देता है, तो किसी का परिणाम शून्य होगा

यदि सरणी अभिव्यक्ति एक अशक्त सरणी देता है, तो ALL का परिणाम शून्य होगा


3

ध्यान दें कि कोई भी / सभी ऑपरेटर ऐरे इंडेक्स के साथ काम नहीं करेंगे। यदि अनुक्रमणिका मन में हैं:

SELECT COUNT(*) FROM "messages" WHERE 3 && recipient_ids

और नकारात्मक:

SELECT COUNT(*) FROM "messages" WHERE NOT (3 && recipient_ids)

एक इंडेक्स तब बनाया जा सकता है जैसे:

CREATE INDEX recipient_ids_idx on tableName USING GIN(recipient_ids)

अन्य उत्तरों के विपरीत, यह उत्तर वास्तव में PostgreSQL सरणी ओवरलैप ऑपरेटर का उपयोग करता है। &&
छत पर गेको

6
यह लिखित रूप में काम नहीं करेगा। सरणी संचालकों जैसे && और @> को दोनों तत्वों को सरणियों की आवश्यकता होती है, जो 3 नहीं है। काम करने के लिए इस के लिए आदेश में, क्वेरी के रूप में लिखा करने की आवश्यकता होगी: SELECT COUNT(*) FROM "messages" WHERE ARRAY[3] && recipient_ids
Dologan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.