दिलचस्प पोस्ट
एंट में <classpath> से स्पष्ट क्लास-पथ जेनरेट करें कई विशेषताओं द्वारा एक सूची को सॉर्ट करें? स्प्रिंग प्रोग्राम के साथ नौकरी का निर्धारण (गतिशील रूप से तयशुदा सेट के साथ) AngularJS: बनाम प्रदाता बनाम कारखाना जावा ईई विनिर्देश और बहु ​​थ्रेडिंग पाइप के साथ कई पॉपेन कमांड लिंक करें HTTP स्ट्रीमिंग लाइव पायथन – मुद्रित आइटम हटाएं और बदलें टिप्पणी DOCTYPE घोषणा से पहले प्रकट हो सकती है? MySQL 2 टेबल में डालें स्ट्रींग सबस्ट्रिंग स्विफ्ट में कैसे काम करती है Jquery.dialog में एक आंशिक दृश्य लोड हो रहा है एक सरल सी # डीएलएल – मैं इसे एक्सेल, एक्सेस, वीबीए, वीबी 6 से कैसे कॉल करूं? जब अजगर एक स्ट्रिंग को प्रशिक्षित करता है किसी सर्वर पर एक छवि के रूप में एक HTML5 कैनवास कैसे सहेज सकता है?

मैं कैसे (या मैं) एकाधिक कॉलम पर अंतर का चयन कर सकता हूँ?

मुझे एक तालिका से सभी पंक्तियों को प्राप्त करने की आवश्यकता है जहां 2 कॉलम संयुक्त हैं, सभी अलग हैं। इसलिए मैं चाहता हूं कि सभी बिक्री जो कि उसी कीमत पर उसी दिन हुई अन्य कोई बिक्री न हो। दिन और कीमत के आधार पर अद्वितीय बिक्री की स्थिति एक सक्रिय स्थिति में अपडेट हो जाएगी।

इसलिए मैं सोच रहा हूं:

UPDATE sales SET status = 'ACTIVE' WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id) FROM sales HAVING count = 1) 

लेकिन मेरा मस्तिष्क इससे कहीं आगे बढ़ने वाला दर्द होता है

वेब के समाधान से एकत्रित समाधान "मैं कैसे (या मैं) एकाधिक कॉलम पर अंतर का चयन कर सकता हूँ?"

 SELECT DISTINCT a,b,c FROM t 

लगभग बराबर है:

 SELECT a,b,c FROM t GROUP BY a,b,c 

ग्रुप बाय सिंटैक्स के लिए उपयोग करने के लिए यह एक अच्छा विचार है, क्योंकि यह अधिक शक्तिशाली है

आपकी क्वेरी के लिए, मैं इसे इस तरह करूँगा:

 UPDATE sales SET status='ACTIVE' WHERE id IN ( SELECT id FROM sales S INNER JOIN ( SELECT saleprice, saledate FROM sales GROUP BY saleprice, saledate HAVING COUNT(*) = 1 ) T ON S.saleprice=T.saleprice AND s.saledate=T.saledate ) 

यदि आप अब तक उत्तरों को एक साथ रखते हैं, तो साफ और सुधार करें, आप इस श्रेष्ठ क्वेरी पर पहुंचेंगे:

 UPDATE sales SET status = 'ACTIVE' WHERE (saleprice, saledate) IN ( SELECT saleprice, saledate FROM sales GROUP BY saleprice, saledate HAVING count(*) = 1 ); 

जो उनमें से किसी की तुलना में बहुत तेज है कारक 10 – 15 (PostgreSQL 8.4 और 9.1 पर मेरे परीक्षणों में) द्वारा वर्तमान स्वीकृत जवाब के निष्पादन के अनुसार।

लेकिन यह अभी भी इष्टतम से दूर है। बेहतर प्रदर्शन के लिए कोई भी NOT EXISTS ( NOT EXISTS -अर्द्ध) उपयोग NOT EXISTS करें। EXISTS मानक एसक्यूएल है, हमेशा के लिए रहा है (कम से कम PostgreSQL 7.2 के बाद, इस सवाल से पहले पूछा गया था) और पूरी तरह से प्रस्तुत आवश्यकताओं को फिट बैठता है:

 UPDATE sales s SET status = 'ACTIVE' WHERE NOT EXISTS ( SELECT 1 FROM sales s1 WHERE s.saleprice = s1.saleprice AND s.saledate = s1.saledate AND s.id <> s1.id -- except for row itself ); AND s.status IS DISTINCT FROM 'ACTIVE'; -- avoid empty updates. see below 

एसक्यूएल फ्यूल्ड

पंक्ति की पहचान करने के लिए अद्वितीय कुंजी

यदि आपके पास टेबल के लिए एक प्राथमिक या अद्वितीय कुंजी नहीं है (उदाहरण के लिए id ), तो आप इस क्वेरी के प्रयोजन के लिए सिस्टम कॉलम ctid साथ प्रतिस्थापित कर सकते हैं (लेकिन कुछ अन्य उद्देश्यों के लिए नहीं):

  AND s.ctid <> s1.ctid 

प्रत्येक तालिका में प्राथमिक कुंजी होना चाहिए यदि आपके पास कोई नहीं था, तो एक को जोड़ें, फिर भी मैं पोस्टग्रेस 10+ में serial या एक IDENTITY कॉलम का सुझाव देता हूं।

यह तेज़ कैसे है?

सबसे पहले शिकार (आगे की तलाश में कोई बात नहीं) के रूप में जल्द से जल्द EXISTS (anti-) अर्द्ध-प्रवेश में subquery का मूल्यांकन करना बंद कर सकता है। कुछ डुप्लिकेट वाली आधार तालिका के लिए यह केवल हल्का और अधिक कुशल है। कई डुप्लिकेट के साथ यह अधिक कुशल बन जाता है

खाली अपडेट बहिष्कृत करें

अगर कुछ या कई पंक्तियों में पहले से ही status = 'ACTIVE' , तो आपका अपडेट कुछ भी नहीं बदलेगा, लेकिन फिर भी पूरी कीमत पर एक छोटी सी पंक्ति संस्करण डालें (मामूली अपवाद लागू होते हैं)। आम तौर पर, आप यह नहीं चाहते हैं। इसे और भी तेज़ बनाने के लिए उपरोक्त प्रदर्शन जैसी एक और WHERE स्थिति जोड़ें:

यदि status को NOT NULL परिभाषित किया गया NOT NULL , तो आप निम्न को आसान बना सकते हैं:

 AND status <> 'ACTIVE'; 

आपकी क्वेरी में समस्या यह है कि जब आप GROUP BY खंड का उपयोग करते हैं (जो कि आप अनिवार्य रूप से अलग से करते हैं) तो आप केवल उन स्तंभों का उपयोग कर सकते हैं जिन्हें आप समूह या कुल कार्य करते हैं आप कॉलम आईडी का उपयोग नहीं कर सकते क्योंकि ये संभावित भिन्न मान हैं आपके मामले में HAVING खंड के कारण हमेशा एक ही मूल्य होता है, लेकिन अधिकांश आरडीबीएमएस यह पहचानने के लिए पर्याप्त नहीं हैं।

यह हालांकि कार्य करना चाहिए (और इसमें शामिल होने की आवश्यकता नहीं है):

 UPDATE sales SET status='ACTIVE' WHERE id IN ( SELECT MIN(id) FROM sales GROUP BY saleprice, saledate HAVING COUNT(id) = 1 ) 

आप MIN के बजाय MAX या AVG का भी उपयोग कर सकते हैं, केवल एक फ़ंक्शन का उपयोग करना महत्वपूर्ण है, जो कॉलम का मान देता है यदि केवल एक मिलान पंक्ति होती है