यह जाँचने के लिए कि क्या एक उपसमुच्चय का एक अलग परिणाम और एक निर्दिष्ट मूल्य संक्षेप में है?


10

मैंने खुद को निम्नलिखित लिखते हुए पाया:

select 'yes' 
where exists(select * from foo where val=1)
and not exists(select * from foo where val<>1);

और अगर बहुत अधिक पठनीयता का त्याग किए बिना अधिक संक्षिप्त तरीका है, तो सोच रहा था।

मुझे एक रास्ता मिला, जिसे मैं एक उत्तर के रूप में पोस्ट कर रहा हूं, लेकिन मैं इससे पूरी तरह से खुश नहीं हूं और विकल्पों में बहुत दिलचस्पी होगी

इस मामले valमें अद्वितीय है foo- कोई डुप्लिकेट नहीं हैं


क्या मैं सही ढंग से समझता हूं कि आप उपनगर के परिणाम में एक पंक्ति चाहते हैं ?
इरविन ब्रान्डस्टेट्टर


जिसका आप शीर्षक में उल्लेख करते हैं। मुझे यकीन नहीं था कि यह "अलग" के बाद या उससे पहले एक परिणाम होना चाहिए।
इरविन ब्रान्डस्टेट्टर

आह हाँ, वह एक :) मैं अपने उत्तर में उप-क्वेरी का भ्रम कर रहा था - आपका कहीं अधिक विशिष्ट और लचीला है, जैसे आप भी उपयोग कर सकते हैं count(distinct val), हालांकि मेरे वास्तविक दुनिया के मामले में इससे कोई फर्क नहीं पड़ता
जैक कहते हैं कि कोशिश करें topanswers.xyz 21

जवाबों:


8

संक्षिप्त, तेज (विशेषकर कई पंक्तियों के साथ), पठनीयता के विषय में मेरा पसंदीदा और द्वंद्व के साथ काम करेगा:

SELECT count(*) = 1 AND min(val) = 1 FROM foo;

रिटर्न TRUE/ FALSE.. या NULL- केवल एक पंक्ति के मामले में val IS NULL, क्योंकि count()कभी रिटर्न NULLया कोई पंक्ति नहीं।

1उदाहरण में दूसरा सिर्फ आपके उदाहरण के कारण पहले जैसा ही होता है।


प्रश्न में क्वेरी NULLमानों के साथ विफल हो जाती है। सरल डेमो पर विचार करें:

CREATE TABLE foo (id int, val int);
INSERT INTO foo VALUES (1, 1),(2, NULL);

SELECT 'yes' 
WHERE      EXISTS(SELECT * FROM foo WHERE val =  1)
AND    NOT EXISTS(SELECT * FROM foo WHERE val <> 1);

IS DISTINCT FROMइसे ठीक कर देंगे, लेकिन यह अभी भी डुप्लिकेट के साथ विफल हो सकता है val- जिसे आपने इस मामले के लिए खारिज कर दिया है।


आपका उत्तर ठीक काम करता है।
रिटर्न 'yes'/ कोई पंक्ति नहीं।

मैं इस छोटे रूप को पसंद करूंगा, हालांकि। मत भूलो कि PostgreSQL (Oracle के विपरीत) में एक उचित booleanप्रकार है

SELECT array_agg(val) = array[1] FROM foo;

रिटर्न TRUE/ FALSE/ NULL


उत्कृष्ट, धन्यवाद, मुझे पता था कि एक बेहतर तरीका होगा :)
जैक कहते हैं कि topanswers.xyz की कोशिश करो

5

@ इरविन के उत्तर पर एक बदलाव। COUNT()बिल्कुल नहीं , केवल MIN()और MAX()। यह बड़ी तालिका के साथ थोड़ा और अधिक कुशल हो सकता है और (आपके मामले में नहीं) डुप्लिकेट val:

SELECT MIN(val) = 1 AND MAX(val) = 1 FROM foo;

+1 धन्यवाद। यह नल को अलग-अलग तरीके से डुप्लिकेट करता है (यदि कोई हो तो)
जैक कहते हैं कि topanswers.xyz का प्रयास करें

@ जैक: हाँ। क्या आपकी टेबल में नल हैं? या आप दोनों मामलों (साथ और बिना) के उत्तर चाहते हैं?
ypercube y

कोई मेरा नहीं है - मैं या तो उपयोग कर सकते हैं :)
जैक कहते हैं topanswers.xyz

एक मिलान सूचकांक के साथ बड़ी तालिकाओं पर बहुत तेजी से होगा , लेकिन ऐसे सूचकांक की अनुपस्थिति में अनौपचारिक प्रदर्शन करता है - जैसे कि क्वेरी परिणामों का परीक्षण करते समय।
इरविन ब्रान्डसेट्टर


1

यह एक रिटर्न true, falseया एक खाली परिणाम:

 select j.val is null 
 from foo left join foo as j on j.val <> foo.val 
 where foo.val = 1 limit 1;

पहली नजर में, इस पर लौटने के लिए प्रतीत नहीं होता falseअगर वहाँ में मान हैं fooजहां val<>1?
जैक का कहना है कि topanswers.xyz

@JackDouglas ओह, क्षमा करें। मैंने पहली बार टास्क को गलत समझा। फिक्स्ड।
ग्रेमप सिप

काम करता है - NULLइस मामले में उस मूल्य को छोड़कर जिसे खारिज नहीं किया गया है।
एरविन ब्रान्डसेट्टर

@ErwinBrandstetter NULLका उपयोग करके IS [NOT] DISTINCT FROMमुझे लगता है कि काम किया जा सकता है।
ग्रेफप सिप

1
@grayhemp: इस मामले में नहीं। LEFT JOIN foo j ON j.val <> foo.valके साथ j.val IS NULLशुरू करने के लिए एक पंक्ति का पता लगाने में विफल रहता है । यदि आप इसे शामिल ON j.val IS DISTINCT FROM foo.valकरते हैं, तो आपको दो मामलों को अलग-अलग बताने के लिए jपरिभाषित किसी अन्य कॉलम पर जांच करने की आवश्यकता होगी NOT NULL। लेकिन कोई अतिरिक्त स्तंभ परिभाषित नहीं है।
इरविन ब्रान्डसेट्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.