पोस्टग्रेज्स: डिस्टिंक्ट लेकिन केवल एक कॉलम के लिए


120

मेरे पास नामों के साथ pgsql पर एक तालिका है (1 mio पंक्तियों से अधिक), लेकिन मेरे पास कई डुप्लिकेट भी हैं। मैं 3 क्षेत्रों का चयन करें: id, name, metadata

मैं उनके साथ बेतरतीब ढंग से चयन करना चाहते हैं ORDER BY RANDOM()और LIMIT 1000, इसलिए मैं यह मेरा PHP स्क्रिप्ट में कुछ स्मृति को बचाने के लिए कई कदम है।

लेकिन मैं ऐसा कैसे कर सकता हूं ताकि यह केवल मुझे एक सूची दे सके जिसमें नामों में कोई डुप्लिकेट न हो।

उदाहरण के लिए [1,"Michael Fox","2003-03-03,34,M,4545"]वापस कर दिया जाएगा, लेकिन नहीं [2,"Michael Fox","1989-02-23,M,5633"]। नाम फ़ील्ड सबसे महत्वपूर्ण है और सूची में अद्वितीय होना चाहिए हर बार जब मैं चयन करता हूं और यह यादृच्छिक होना चाहिए।

मैं के साथ की कोशिश की GROUP BY name, बू तो यह मुझे आईडी और मेटाडाटा के GROUP BYरूप में अच्छी तरह से या एक aggragate समारोह में होने की उम्मीद है, लेकिन मैं उन्हें किसी भी तरह से फ़िल्टर करना नहीं चाहता।

किसी को भी पता है कि कैसे कई कॉलम लाने हैं लेकिन क्या केवल एक कॉलम पर एक अलग है?

जवाबों:


226

केवल एक (या n) कॉलम पर कुछ करने के लिए:

select distinct on (name)
    name, col1, col2
from names

यह नाम वाली किसी भी पंक्ति को वापस कर देगा। यदि आप नियंत्रित करना चाहते हैं कि कौन सी पंक्तियों को वापस करना होगा तो आपको ऑर्डर करने की आवश्यकता होगी:

select distinct on (name)
    name, col1, col2
from names
order by name, col1

कॉल 1 द्वारा आदेश दिए जाने पर पहली पंक्ति वापस आ जाएगी।

distinct on:

चयनित सूची (अभिव्यक्ति [, ...]) उन पंक्तियों के प्रत्येक सेट की केवल पहली पंक्ति रखता है, जहाँ दिए गए भाव समान हैं। अभिव्यक्तियों पर DISTINCT की व्याख्या ORDER BY (ऊपर देखें) के समान नियमों का उपयोग करके की जाती है। ध्यान दें कि प्रत्येक सेट की "पहली पंक्ति" अप्रत्याशित है जब तक कि यह सुनिश्चित करने के लिए ORDER BY का उपयोग नहीं किया जाता है कि वांछित पंक्ति पहले दिखाई देती है।

DISTINCT ON अभिव्यक्ति (ओं) को सबसे बाईं ओर अभिव्यक्ति (s) से मेल खाना चाहिए। ORDER BY क्लॉज में आम तौर पर अतिरिक्त अभिव्यक्ति (ओं) को शामिल किया जाएगा जो समूह में प्रत्येक DISTINCT पर पंक्तियों की वांछित पूर्ववर्तीता निर्धारित करते हैं।


ऑर्डर देने पर अच्छी पकड़। मैंने इसे शामिल नहीं किया क्योंकि वे एक यादृच्छिक क्रम चाहते हैं, लेकिन वैसे भी उल्लेख करना महत्वपूर्ण है।
क्रेग रिंगर

है order by nameआवश्यक है? क्या यह एक अलग परिणाम देगा order by col1?
इलियट संभावना 2

1
@ बेलॉट हां nameजरूरी है। distinct onमैनुअल पर जाँच करें ।
क्लोडोल्डो नेटो

1
काश TSQL टीम ऐसा करने का एक समझदार तरीका प्रदान कर सकती।
जेटीडब्ल्यू

कृपया उपयुक्त पोस्टग्रैसक्ल संदर्भ
ओगागा उज़ोह

17

किसी को भी पता है कि कैसे कई कॉलम लाने हैं लेकिन क्या केवल एक कॉलम पर एक अलग है?

आप चाहते हैं खंडDISTINCT ON

आपने नमूना डेटा या पूर्ण क्वेरी प्रदान नहीं की, इसलिए मेरे पास आपको दिखाने के लिए कुछ भी नहीं है। आप कुछ लिखना चाहते हैं:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table;

यह पंक्तियों के एक अप्रत्याशित (लेकिन "यादृच्छिक") सेट को नहीं लौटाएगा। यदि आप इसे अनुमानित करना चाहते हैं तो ORDER BYप्रति क्लोडाल्डो के उत्तर को जोड़ दें। यदि आप इसे वास्तव में यादृच्छिक बनाना चाहते हैं, तो आप चाहते हैं ORDER BY random()


बस इस DISTINCT ON को क्लॉज पर ध्यान दें, आप केवल एक ही चीज + से ज्यादा ऑर्डर कर सकते हैं। इसलिए यदि आप DISTINCT ON (नाम) कहते हैं, तो आपको नाम से ORDER करना होगा, फिर जो आप चाहते हैं। शायद ही आदर्श।
केविन पार्कर

केविन, आप केवल बाहरी क्वेरी में एक सीटीई या सबक्वेरी-इन-एफओआर और ओआरडीईआर का उपयोग कर सकते हैं
क्रेग रिंगर

हां, और प्रदर्शन को देखने जाएं ... सूचकांक स्थान से संपूर्ण संभावित परिणाम खोजे जाएंगे। यह बदल जाता है क्या कर सकता है एक 900ms एक में सही सूचकांक के साथ एक 10-20ms पूछताछ हो सिर्फ इसलिए कि posgres द्वारा एक अलग अलग / आदेश नहीं संभाल सकते हैं। इससे कोई फर्क नहीं पड़ता कि बाहरी क्वेरी क्रम क्या है, यह पहले मैच को खोजने के लिए आंतरिक उपकुंजी से सूचकांक का उपयोग करने जा रहा है, फिर पुन: सॉर्ट करता है। Dba.stackexchange.com/questions/260852/…
केविन पार्कर

4
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME

2
बस सावधानी का एक शब्द: जो ID मान या मेटाडेटा मान जो "एक साथ" नहीं दे सकता है
a_horse_with_no_name

@ नोवम नं। इसका मतलब है कि यह माइकल की पंक्तियों और मेटाडाटा में से किसी एक से एक आईडी वैल्यू लेता है क्योंकि यह माइकल के मैक्स के लिए पूछा गया था।
क्लोडोल्डो नेटो

ठीक है, यह बहुत हद तक वास्तविक डेटा ओपी उपयोगों पर निर्भर करता है, जिनसे मैं बिल्कुल अनभिज्ञ हूं। आपको MIN या जो भी हो, का उपयोग करने की आवश्यकता हो सकती है। बस यह प्रदर्शित किया जाता है कि आप फ़ील्ड को शामिल नहीं कर सकते हैं, न कि किसी GROUP BYखंड पर।
डेविड जाशी

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