MySQL एक कॉलम DISTINCT का चयन करता है, जो अन्य कॉलम के साथ होता है


192
ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson

मैं कॉलम DISTINCTसे परिणाम का चयन करना चाहता हूं FirstName, लेकिन मुझे संबंधित IDऔर की आवश्यकता है LastName

परिणाम सेट को केवल एक दिखाने की जरूरत है John, लेकिन डो IDके 1 और ए LastNameके साथ।


1
आप एक अलग प्रथम नाम के साथ निम्नतम ID से संबंधित अंतिम नाम चाहते हैं?
थॉमस लैंगस्टन

3
वह कौन सा तर्क है जो शीर्ष एक के चयन में जाना चाहिए? मुझे लगता है कि आप जॉन डो और जॉन जॉनसन दोनों को दिखाना चाहेंगे क्योंकि वे दो अलग-अलग जॉन्स हैं, लेकिन यह सिर्फ मैं ही हूं।
जूडा

4
DISTINCTकोई फ़ंक्शन नहीं है। के साथ सभी उत्तर DISTINCT()गलत हैं। जब आप इसे नहीं रखेंगे तब त्रुटि दिखाई देगी SELECT
प्रश्न अतिप्रवाह

1
ALL शब्द अलग होने के बाद कोष्ठक के उपयोग के उत्तर वास्तव में गलत हैं। डिस्टिंक्ट एक फ़ंक्शन नहीं है इसलिए यह एक पैरामीटर को स्वीकार नहीं कर सकता है। अलग-अलग निम्नलिखित कोष्ठकों को केवल अनदेखा किया जाता है। जब तक आप PostgreSQL का उपयोग नहीं कर रहे हैं, जहां कोष्ठक एक "जटिल डेटा प्रकार"
बनाएगा

जवाबों:


192

इस क्वेरी को आज़माएं

 SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)

15
हमें कैसे पता चलेगा कि किस पंक्ति को लौटाया जाएगा?
विलियम एंट्रीकेन

26
@ निर्णय के अनुसार, आप MySQL प्रलेखन के अनुसार नहीं कर सकते हैं : "सर्वर प्रत्येक समूह से किसी भी मूल्य का चयन करने के लिए स्वतंत्र है, इसलिए जब तक वे समान नहीं होते हैं, तब तक चुने गए मान अनिश्चित होते हैं।" व्यवहार में मैंने इस तरह के प्रश्नों का सफलतापूर्वक ORDER BY खंड के साथ उपयोग किया है, उदाहरण के लिए आप ORDER BY id ASC / DESC और MySQL जोड़ सकते हैं और हर बार जब आप क्वेरी को निष्पादित करेंगे, तो लगातार परिणाम लौटेंगे। लेकिन मुझे यकीन है कि किसी को भी उत्पादन वातावरण में अनिर्दिष्ट सुविधाओं का उपयोग करना चाहिए।
अरुण जूनविकियस

2
ओपी mysql संस्करण का उल्लेख नहीं करता है।
डायो

2
@sinaza ने MySQL के 5.7.5+लिए मेरे अपडेट किए गए जवाब को बदले हुए GROUP BYहैंडल के लिए देखें
fyrye

3
यह केवल_फुल_ग्रुप_बी मोड के साथ काम नहीं करता है क्योंकि न तो ID और न ही LastName न तो एकत्रित होता है और न ही ग्रुपिंग फ़ंक्शन का हिस्सा होता है। मदद!
इहोडोंल्ड

63

DISTINCTकीवर्ड वास्तव में जिस तरह से आप के लिए यह उम्मीद कर रहे हैं काम नहीं करता। जब आप उपयोग SELECT DISTINCT col1, col2, col3करते हैं तो आप वास्तव में सभी अद्वितीय {col1, col2, col3} tuples का चयन करते हैं।


14
इस ब्रायन को इंगित करने के लिए धन्यवाद। क्या आप एक उदाहरण प्रदान कर सकते हैं कि मैं एक ही परिणाम प्राप्त करने के लिए ग्रुप बाय का उपयोग कैसे कर सकता हूं?
mr

59

GROUP BYबिना किसी समुच्चय फ़ंक्शन का उपयोग करते हुए संभावित अप्रत्याशित परिणामों से बचने के लिए , जैसा कि स्वीकृत उत्तर में उपयोग किया जाता है , क्योंकि MySQL एक समुच्चय फ़ंक्शन [sic] का उपयोग नहीं करते हुए समूहीकृत डेटा सेट के भीतर किसी भी मूल्य को पुनः प्राप्त करने के लिए स्वतंत्र है और मुद्दों के साथ । कृपया बहिष्करण जॉइन का उपयोग करने पर विचार करें।ONLY_FULL_GROUP_BY

बहिष्करण में शामिल हों - अस्पष्ट इकाइयाँ

प्रथमनाम और अंतिमनाम को विशिष्ट रूप से अनुक्रमित (असंदिग्ध) मानकर, परिणाम सेट को फ़िल्टर करने के GROUP BYलिए सॉर्ट करने के लिए एक विकल्प है LEFT JOIN, अन्यथा एक बहिष्करण JOIN के रूप में जाना जाता है।

प्रदर्शन देखें

आरोही क्रम (AZ)

AZ से lastname द्वारा दिए गए पहले फर्स्टनाम को पुनः प्राप्त करने के लिए

सवाल

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;

परिणाम

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  1 |      John |      Doe |

अवरोही क्रम (ZA)

ZA से lastname द्वारा दिए गए पहले फर्स्टनाम को पुनः प्राप्त करने के लिए

सवाल

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;

परिणाम

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  3 |      John |  Johnson |

तब आप परिणामी डेटा को इच्छानुसार ऑर्डर कर सकते हैं।


बहिष्करण में शामिल हों - अस्पष्ट इकाइयाँ

यदि पहला और अंतिम नाम संयोजन अद्वितीय (अस्पष्ट) नहीं है और आपके पास समान मानों की एक से अधिक पंक्तियाँ हैं, तो आप परिणाम को फ़िल्टर करने के लिए JOIN मानदंड पर एक शर्त शामिल करके आईडी द्वारा फ़िल्टर भी कर सकते हैं।

प्रदर्शन देखें

table_name डेटा

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')

सवाल

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;

परिणाम

| id | firstname | lastname |
|----|-----------|----------|
|  1 |      John |      Doe |
|  2 |      Bugs |    Bunny |

सबक्वीरी का आदेश दिया

संपादित करें

एक आदेशित उपशम का उपयोग करते हुए मेरा मूल उत्तर , MySQL 5.7.5 से पहले लिखा गया था , जो कि अब लागू नहीं है, इसके परिवर्तनों के कारण ONLY_FULL_GROUP_BY। कृपया इसके बजाय ऊपर दिए गए उदाहरणों में शामिल होने के बहिष्करण का उपयोग करें।

यह नोट करना भी महत्वपूर्ण है; जब ONLY_FULL_GROUP_BYअक्षम किया जाता है (MySQL 5.7.5 से पहले मूल व्यवहार) , GROUP BYएक कुल कार्य के बिना उपयोग अप्रत्याशित परिणाम प्राप्त कर सकता है, क्योंकि MySQL समूहीकृत डेटा सेट के भीतर किसी भी मूल्य को चुनने के लिए स्वतंत्र है [sic]

अर्थ IDया lastnameमान को पुनः प्राप्त किया जा सकता है जो पुनः प्राप्त पंक्ति से संबद्ध नहीं हैfirstname


चेतावनी

MySQL के GROUP BYसाथ प्रयोग किए जाने पर अपेक्षित परिणाम नहीं मिल सकता हैORDER BY

देखें टेस्ट केस का उदाहरण

कार्यान्वयन का सबसे अच्छा तरीका, अपेक्षित परिणाम सुनिश्चित करने के लिए, एक आदेशित उपवर्ग का उपयोग करके परिणाम सेट गुंजाइश को फ़िल्टर करना है।

table_name डेटा

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')

सवाल

SELECT * FROM (
    SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName

परिणाम

| ID | first |    last |
|----|-------|---------|
|  2 |  Bugs |   Bunny |
|  3 |  John | Johnson |

तुलना

के GROUP BYसाथ संयोजन में उपयोग करते समय अप्रत्याशित परिणाम प्रदर्शित करने के लिएORDER BY

सवाल

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC

परिणाम

| ID | first |  last |
|----|-------|-------|
|  2 |  Bugs | Bunny |
|  1 |  John |   Doe |

3
अधिकांश पूर्ण उत्तर तक। पहली क्वेरी में 'ID desc' को 'ID asc' में बदलने से हम या तो 'जॉन डो' या 'जॉन जॉनसन' को पुनः प्राप्त कर सकते हैं। दूसरी क्वेरी में 'ID desc' को बदलने से यह प्रभाव नहीं पड़ता है।
कार्ला

पोस्टग्रेज पर आपको mysql के बारे में सुनिश्चित न करके समूह में आईडी की आवश्यकता होती है।
सचिन प्रसाद

क्या एक सेलेक्ट में कॉलम-बी से एक ग्रुप बाय-बी एक सेलेक्ट स्टेटमेंट हमेशा MyriaDB के लेटेस्ट वर्जन के साथ सही तरीके से काम करेगा?
नील डेविस

@NealDavis MariaDB मैनुअल के अनुसार Ordering is done after grouping., इसलिए इस उपयोग के मामले में नहीं, इसके अलावा MariaDB ORDER BY को उप-वर्गों में (SQL मानक के अनुसार) बिना अनदेखा करता है LIMIT। आप डीबीएWindow Function
स्टैकएक्सचेंज

1
@ नेट्स नहीं, GROUP BYसमूहीकृत डेटा सेट के भीतर किसी भी मूल्य का चयन कर सकते हैं, जब तक कि उन कॉलम पर एक विशिष्ट फ़ंक्शन का उपयोग किसी विशिष्ट मूल्य को बाध्य करने के लिए नहीं किया जाता है। तो lastnameया idआदेशित पंक्तियों में से किसी से भी आ सकता है। मूल उप-उदाहरण उदाहरण डिफ़ॉल्ट रूप से स्वीकार्य था MySQL <= 5.7.4लेकिन तकनीकी रूप से अभी भी समस्या से ग्रस्त है। हालांकि यह ORDER BYएक यादृच्छिक चयन को रोकने में मदद करता है, यह अभी भी सैद्धांतिक रूप से संभव है, लेकिन ORDER BYउप-वर्ग का उपयोग किए बिना की तुलना में काफी कम संभावना है ।
fyrye



3

कैसा रहेगा

`SELECT 
    my_distinct_column,
    max(col1),
    max(col2),
    max(col3)
    ...
 FROM
    my_table 
 GROUP BY 
    my_distinct_column`

2

निश्चित नहीं है कि आप MySQL के साथ ऐसा कर सकते हैं, लेकिन आप T-SQL में CTE का उपयोग कर सकते हैं

; WITH tmpPeople AS (
 SELECT 
   DISTINCT(FirstName),
   MIN(Id)      
 FROM People
)
SELECT
 tP.Id,
 tP.FirstName,
 P.LastName
FROM tmpPeople tP
JOIN People P ON tP.Id = P.Id

अन्यथा आपको एक अस्थायी तालिका का उपयोग करना पड़ सकता है।


1

जैसा कि fyrye द्वारा बताया गया है , स्वीकृत उत्तर MySQL के पुराने संस्करणों से संबंधित है जिसमें ONLY_FULL_GROUP_BYअभी तक पेश नहीं किया गया था। MySQL 8.0.17 के साथ (इस उदाहरण में प्रयुक्त), जब तक आप अक्षम नहीं करते ONLY_FULL_GROUP_BYआपको निम्न त्रुटि संदेश मिलेगा:

mysql> SELECT id, firstName, lastName FROM table_name GROUP BY firstName;

त्रुटि 1055 (42000): चयन सूची का अभिव्यक्ति # 1 समूह द्वारा खंड में नहीं है और इसमें गैर-अलग-अलग कॉलम 'mydatabase.table_name.id' शामिल है जो ग्रुप BY खंड में स्तंभों पर कार्यात्मक रूप से निर्भर नहीं है; यह sql_mode = only_full_group_by के साथ असंगत है

इसके चारों ओर काम करने का एक तरीका fyrye द्वारा उल्लेख नहीं किया गया है , लेकिन https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html में वर्णित है , इस ANY_VALUE()फ़ंक्शन को स्तंभों पर लागू करना है GROUP BYखंड में नहीं ( idऔर lastNameइस उदाहरण में):

mysql> SELECT ANY_VALUE(id) as id, firstName, ANY_VALUE(lastName) as lastName FROM table_name GROUP BY firstName;
+----+-----------+----------+
| id | firstName | lastName |
+----+-----------+----------+
|  1 | John      | Doe      |
|  2 | Bugs      | Bunny    |
+----+-----------+----------+
2 rows in set (0.01 sec)

जैसा कि पूर्वोक्त डॉक्स में लिखा गया है,

इस स्थिति में, MySQL प्रत्येक नाम समूह के भीतर पते के मानों के नॉनडेटर्मिनिज़्म को अनदेखा करता है और क्वेरी को स्वीकार करता है। यह उपयोगी हो सकता है यदि आप बस परवाह नहीं करते हैं कि प्रत्येक समूह के लिए एक गैर-पृथक कॉलम का कौन सा मूल्य चुना जाता है। ANY_VALUE()इस तरह के SUM()या के रूप में कार्यों के विपरीत, एक कुल समारोह नहीं है COUNT()। यह बस nondeterminism के लिए परीक्षण को दबाने का काम करता है।


स्पष्टीकरण के लिए, मैंने विशेष ANY_VALUE()रूप से अपने उत्तर के रूप में उपयोग करने का सुझाव देने से परहेज किया और टिप्पणियों को अस्पष्ट और अप्रत्याशित परिणाम-सेट को रोकने पर केंद्रित है। चूंकि फ़ंक्शन नाम से पता चलता है, यह चयनित पंक्तियों से किसी भी मूल्य के परिणामस्वरूप प्राप्त किया जा सकता है। मैं सुझाव देता हूं कि इसका उपयोग करना चाहिए MAXया MINइसके बजाय।
17

0

ध्यान रखें कि जब MySQL द्वारा समूह का उपयोग किया जाता है, तो केवल डेटाबेस ही होता है, जो समूह द्वारा कॉलम का उपयोग करने की अनुमति देता है और / या उस टुकड़े द्वारा आदेश का चयन करता है जो कि चयनित कथन का हिस्सा नहीं है।

इसलिए उदाहरण के लिए: column3 द्वारा column2 क्रम द्वारा तालिका समूह से column1 का चयन करें

वह अन्य डेटाबेस जैसे Postgres, Oracle, MSSQL इत्यादि में नहीं उड़ेंगे। आपको उन डेटाबेस में निम्नलिखित कार्य करने होंगे

कॉलम 3 द्वारा कॉलम 2 ऑर्डर द्वारा कॉलम समूह से कॉलम 1, कॉलम 2, कॉलम 3 का चयन करें

यदि आप कभी भी अपने वर्तमान कोड को किसी अन्य डेटाबेस में स्थानांतरित करते हैं या किसी अन्य डेटाबेस में काम करना शुरू करते हैं और कोड का पुन: उपयोग करने का प्रयास करते हैं तो बस कुछ जानकारी।


-2

आप अलग-अलग मानों और इसी क्षेत्रों के प्रदर्शन के लिए समूह का उपयोग कर सकते हैं।

select * from tabel_name group by FirstName

अब आपको इस तरह आउटपुट मिला:

ID    FirstName     LastName
2     Bugs          Bunny
1     John          Doe


अगर आप जवाब देना चाहते हैं

ID    FirstName     LastName
1     John          Doe
2     Bugs          Bunny

फिर इस क्वेरी का उपयोग करें,

select * from table_name group by FirstName order by ID

2
यह हमेशा अपेक्षित परिणाम नहीं देगा जब
बजे

-3
SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName

सबसे अच्छा शर्त IMO होगा


32
यह काम नहीं करेगा, यह अलग मूल्यांकन में आईडी और अंतिम नाम भी लेगा।
लूडो -

2
यह DISTINCT (firstName, ID, LastName) के समान है
टॉम टेलर

-4
SELECT DISTINCT (column1), column2
FROM table1
GROUP BY column1

1
DISTINCT()कोई फ़ंक्शन नहीं है। इसके अलावा DISTINCT और GROUP BY एक ही काम कर रहे हैं, इसलिए कोई कारण नहीं है उन दोनों को।
मार्की 555

यह एक कुशल कथन नहीं है, आपको DISTINCT या Group By दोनों का उपयोग करना चाहिए।
संकोचन १
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.