जाँचें कि क्या मान Postgres सरणी में मौजूद है


196

9.0 पोस्टग्रेज का उपयोग करते हुए, मुझे यह जांचने का एक तरीका चाहिए कि क्या किसी दिए गए सरणी में कोई मान मौजूद है। अब तक मैं कुछ इस तरह से आया:

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

लेकिन मुझे लगता है कि इसका एक सरल तरीका होना चाहिए, मैं इसे नहीं देख सकता। यह बेहतर लगता है:

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

मेरा मानना ​​है कि यह पर्याप्त होगा। लेकिन अगर आपके पास इसे करने के अन्य तरीके हैं, तो कृपया साझा करें!

जवाबों:


323

ANYनिर्माण के साथ सरल :

SELECT value_variable = ANY ('{1,2,3}'::int[])

ANY(कोष्ठकों के बीच) का सही संचालक या तो एक सेट (एक उपसमुच्चय का परिणाम, उदाहरण के लिए) या एक सरणी हो सकता है । इसका उपयोग करने के कई तरीके हैं:

महत्वपूर्ण अंतर: एरे ऑपरेटर्स ( <@और @>, &&एट अल।) ऑपरग्रिड्स के रूप में सरणी प्रकारों की अपेक्षा करते हैं और पोस्टग्रेक्यूएल के मानक वितरण में जीआईएन या जीआईएसटी सूचकांकों का समर्थन करते हैं, जबकि ANYनिर्माण एक तत्व प्रकार को बाएं ऑपरेंड की उम्मीद करता है और इन सूचकांकों का समर्थन नहीं करता है। उदाहरण:

इसमें से कोई भी NULLतत्वों के लिए काम नहीं करता है । के लिए परीक्षण करने के लिए NULL:


धन्यवाद। मैनुअल के उस हिस्से को छोड़ दिया जाना चाहिए। यह बहुत अच्छा काम करता है। इसमें ऑटोमैटिक कास्टिंग का साइड इफेक्ट है। Ex: SELECT 1 :: smallint = Any ('{1,2,3}' :: int []] काम करता है। बस अभिव्यक्ति के दाईं ओर कोई भी () डालना सुनिश्चित करें।
माइक स्टारोव

जवाब के लिए धन्यवाद। एक समस्या मिली जहां मेरी क्वेरी ने स्थानीय पर काम किया, लेकिन हरोकू में इस संदेश को फेंक दिया गया ANY/ALL (array) requires array on right side, ::int[]आकर्षण का जोड़ ।
किंडर डेफ

जहाँ S.employee_id <@ any ('' '+ employeeIDsArray +' ':: int []) यह PSQLException: ERROR: अनुपलब्ध आयाम मान
रामप्रसाद

3
यद्यपि यह इंटरनेट वर्षों में एक डायनासोर का सवाल है, मेरे जैसे धीमे लोगों को जागरूक किया जाना चाहिए 'something' = ANY(some_array)जो एक WHEREखंड में भी इस्तेमाल किया जा सकता है । केवल क्रॉम के लिए ज्ञात कारणों से, मैंने पिछले चार साल यह सोचकर बिताए हैं कि मैं WHEREखंडों में सरणी तुलनित्र का उपयोग नहीं कर सकता । वे दिन अब चले गए। (मुझे एक बच्चे के रूप में मेरे सिर पर गिरा दिया गया था, इसलिए शायद यह सिर्फ मेरे लिए है)।
जी.टी.

1
@GT: इसका सार: कोई भी boolean अभिव्यक्ति WHEREक्लॉज में काम करती है - क्रॉम की इच्छा।
एरविन ब्रांडस्टेट्टर

90

मेरे द्वारा प्राप्त किए गए जाल के लिए देखें: जब जाँच करना कि कोई मान किसी सरणी में मौजूद नहीं है, तो आपको ऐसा नहीं करना चाहिए:

SELECT value_variable != ANY('{1,2,3}'::int[])

लेकिन उपयोग करें

SELECT value_variable != ALL('{1,2,3}'::int[])

बजाय।


2
एक डबल नकारात्मक की तरह; ALLANY
Vol7ron

43
SELECT NOT value_variable = ANY('{1,2,3}'::int[])अधिक पठनीय हो सकता है
Ondřej Bouda

28

लेकिन अगर आपके पास इसे करने के अन्य तरीके हैं तो कृपया साझा करें।

आप दो सरणियों की तुलना कर सकते हैं। यदि बाएं सरणी में कोई भी मान दाएं सरणी में ओवरलैप करता है, तो यह सही है। यह एक प्रकार का हैकिश है, लेकिन यह काम करता है।

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • पहली और दूसरी क्वेरी में, मान 1सही सरणी में है
  • ध्यान दें कि दूसरा क्वेरी है true, भले ही मान 4सही सरणी में निहित नहीं है
  • तीसरी क्वेरी के लिए, बाएं सरणी में कोई मान (यानी, 4) सही सरणी में नहीं है, इसलिए यह वापस आ जाता हैfalse

सरणी में मान रखने के लिए मैं किसी अन्य तालिका के कॉलम की खोज कैसे कर सकता हूं? उदाहरण के लिए, बीयर्स में से जहां style_id इन करें (उन यूज़र्स से प्राथमिकताएँ जहाँ id = 1) सीमा 1; style_id एक पूर्णांक डेटा प्रकार है; प्राथमिकताएँ पूर्णांक होती हैं [] मुझे यह त्रुटि मिलती है त्रुटि: ऑपरेटर मौजूद नहीं है: पूर्णांक = पूर्णांक [] लाइन 1: बीयर्स से चुनें जहां style_id में (चयन वरीयताएँ f ... ^ HINT: कोई ऑपरेटर दिए गए नाम और तर्क प्रकार से मेल नहीं खाता है (एस)। आपको स्पष्ट प्रकार की जातियों को जोड़ने की आवश्यकता हो सकती है।
एचपी

@HP उस सवाल को हल करने के अलग-अलग तरीके हैं, आपको एक नया सवाल पूछना चाहिए
vol7ron

क्या आप सुनिश्चित हैं कि कोई मौजूदा प्रश्न नहीं है? @ Vol7ron
HP

@HP बिल्कुल नहीं, लेकिन टिप्पणियाँ किसी प्रश्न या उत्तर से संबंधित टिप्पणियों के लिए हैं; आम तौर पर अधिक जानकारी जोड़ने या अधिक जानकारी को हल करने के लिए जिसे संबोधित नहीं किया गया था। आप एक ऐसा प्रश्न पूछ रहे हैं जो इस उत्तर से संबंधित नहीं है। मुझे लगता है कि आप अपने प्रश्न को एक नई पोस्ट के रूप में पूछकर नहीं, बल्कि टिप्पणी के द्वारा अधिक भाग्य पाएंगे;)
vol7ron

@ यदि आपने अपना प्रश्न पोस्ट नहीं किया है तो आप यहां देख सकते हैं: sqlfiddle.com/# -15 / 144cd/ 3 उदाहरण के लिए कि आपको क्या करने की आवश्यकता है - आपका मुद्दा अलग है क्योंकि आपको अपने सरणी को बेकार करना होगा।
Vol7ron

4

unnestके रूप में अच्छी तरह से इस्तेमाल किया जा सकता है। यह पंक्तियों का एक सेट करने के लिए सरणी का विस्तार और फिर बस एक मूल्य की जाँच से मौजूद है या नहीं का उपयोग कर के रूप में सरल रूप में है INया NOT IN

जैसे

  1. id => uuid

  2. exception_list_ids => UUID []

select * from table where id NOT IN (select unnest(exception_list_ids) from table2)


हाँ। ध्यान दें कि मेरी क्वेरी में सेलेक्ट UNNEST उतना अच्छा नहीं है जितना = कोई भी। मैं यह देखने के लिए कि क्या आप चाहते हैं / उम्मीद करते हैं, यह देखने के लिए क्वेरी योजनाओं की जांच करने की सलाह देंगे।
रॉब बेग्रेव

3

किसी सरणी में एक तत्व के अस्तित्व की तलाश में, पोस्टग्रेज के एसक्यूएल पार्सर को पास करने के लिए उचित कास्टिंग की आवश्यकता होती है। यहां एक उदाहरण क्वेरी का उपयोग करते हुए एरे में शामिल क्लॉज में ऑपरेटर होता है:

सादगी के लिए मैं केवल संबंधित भाग सूचीबद्ध करता हूं:

table1 other_name text[]; -- is an array of text

दिखाया गया SQL का सम्मिलित भाग

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

निम्नलिखित भी काम करता है

on t2.panel = ANY(t1.other_name)

मैं सिर्फ यह अनुमान लगा रहा हूं कि अतिरिक्त कास्टिंग की आवश्यकता है क्योंकि पार्स को सटीक प्रकार के कॉलम का पता लगाने के लिए तालिका परिभाषा लाने की आवश्यकता नहीं है। अन्य कृपया इस पर टिप्पणी करें।


1

हाय कि एक मेरे लिए ठीक काम करता है, शायद किसी के लिए उपयोगी है

अपने से चुनें * जहाँ पर array_column :: text ilike any (ARRAY ['% text_to_search%' :: text]) का चयन करें;

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