SQL द्वारा अद्वितीय रिकॉर्ड का चयन कैसे करें


87

जब मैं "SELECT * FROM टेबल" करता हूं तो मुझे नीचे दिए गए परिणाम मिलते हैं:

1 item1 data1
2 item1 data2
3 item2 data3
4 item3 data4

जैसा कि आप देख सकते हैं, कॉलम 2 से आइटम रिकॉर्ड हैं (आइटम 1 डूबा हुआ है)। तो मैं इस तरह से कैसे परिणाम प्राप्त कर सकता हूं:

1 item1 data1
2 item2 data3
3 item3 data4

केवल एक रिकॉर्ड डुप्लिकेट से लौटाया जाता है, साथ ही बाकी अनोखे रिकॉर्ड के साथ।


आइटम 1 को तकनीकी रूप से डुप्लिकेट नहीं किया गया है। जैसा कि दिखाया गया है, पंक्तियाँ 1 और 2 अद्वितीय अवलोकन हैं। क्या होगा यदि आप पंक्ति 2 और पंक्ति 1 नहीं रखना चाहते हैं?
साइबरनेट

जवाबों:


105

distinctएकल और कई कॉलम नामों वाले कीवर्ड के साथ, आपको अलग-अलग रिकॉर्ड मिलते हैं:

SELECT DISTINCT column 1, column 2, ...
FROM table_name;

14
क्या ऐसा हो सकता है कि उत्तर वास्तव में गलत हो? DISTINCT सभी चयनित कॉलम (कम से कम DB2 पर) पर लागू होता है, जो अभी भी व्यक्तिगत कॉलम में डुप्लिकेट मान लौटाएगा।
कॉन्स्टेंटिन

26

यदि आपको केवल डुप्लिकेट निकालने की आवश्यकता है तो उपयोग करें DISTINCTGROUP BYप्रत्येक समूह में कुल संचालकों को लागू करने के लिए उपयोग किया जाना चाहिए

ग्रुप बी वी DISTINCT द्वारा


11

यह निर्भर करता है कि आप प्रत्येक अद्वितीय आइटम के लिए किस पंक्ति में वापस लौटना चाहते हैं। आपका डेटा SQL सर्वर के लिए इस उदाहरण में न्यूनतम डेटा मान इंगित करता है।

SELECT item, min(data)
FROM  table
GROUP BY item

10

4 तरीके हैं जिनका आप उपयोग कर सकते हैं:

  1. DISTINCT
  2. समूह द्वारा
  3. सबक्वेरी
  4. ROW_NUMBER () के साथ सामान्य टेबल एक्सप्रेशन (CTE)

TABLEपरीक्षण डेटा के साथ निम्नलिखित नमूने पर विचार करें :

/** Create test table */
CREATE TEMPORARY TABLE dupes(word text, num int, id int);

/** Add test data with duplicates */
INSERT INTO dupes(word, num, id)
VALUES ('aaa', 100, 1)
      ,('bbb', 200, 2)
      ,('ccc', 300, 3)
      ,('bbb', 400, 4)
      ,('bbb', 200, 5)     -- duplicate
      ,('ccc', 300, 6)     -- duplicate
      ,('ddd', 400, 7)
      ,('bbb', 400, 8)     -- duplicate
      ,('aaa', 100, 9)     -- duplicate
      ,('ccc', 300, 10);   -- duplicate

विकल्प 1: DISTINCT का चयन करें

यह सबसे सरल और सीधे आगे है, लेकिन सबसे सीमित तरीका भी है:

SELECT DISTINCT word, num 
FROM    dupes
ORDER BY word, num;

/*
word|num|
----|---|
aaa |100|
bbb |200|
bbb |400|
ccc |300|
ddd |400|
*/

विकल्प 2: ग्रुप बाय

समूहीकरण आप समेकित डेटा को जोड़ने के लिए, की तरह की अनुमति देता है min(id), max(id), count(*), आदि:

SELECT  word, num, min(id), max(id), count(*)
FROM    dupes
GROUP BY word, num
ORDER BY word, num;

/*
word|num|min|max|count|
----|---|---|---|-----|
aaa |100|  1|  9|    2|
bbb |200|  2|  5|    2|
bbb |400|  4|  8|    2|
ccc |300|  3| 10|    3|
ddd |400|  7|  7|    1|
*/

विकल्प 3: उपशम

एक उप-वर्ग का उपयोग करते हुए, आप पहले नकली पंक्तियों को अनदेखा करने के लिए पहचान सकते हैं, और फिर WHERE NOT IN (subquery)निर्माण के साथ बाहरी क्वेरी में उन्हें फ़िल्टर कर सकते हैं :

/** Find the higher id values of duplicates, distinct only added for clarity */
    SELECT  distinct d2.id
    FROM    dupes d1
        INNER JOIN dupes d2 ON d2.word=d1.word AND d2.num=d1.num
    WHERE d2.id > d1.id

/*
id|
--|
 5|
 6|
 8|
 9|
10|
*/

/** Use the previous query in a subquery to exclude the dupliates with higher id values */
SELECT  *
FROM    dupes
WHERE   id NOT IN (
    SELECT  d2.id
    FROM    dupes d1
        INNER JOIN dupes d2 ON d2.word=d1.word AND d2.num=d1.num
    WHERE d2.id > d1.id
)
ORDER BY word, num;

/*
word|num|id|
----|---|--|
aaa |100| 1|
bbb |200| 2|
bbb |400| 4|
ccc |300| 3|
ddd |400| 7|
*/

विकल्प 4: ROW_NUMBER () के साथ सामान्य तालिका अभिव्यक्ति

सामान्य तालिका अभिव्यक्ति (CTE) में, समूह कॉलम द्वारा विभाजित ROW_NUMBER () का चयन करें, और वांछित क्रम में ऑर्डर करें। फिर केवल उन अभिलेखों का चयन करें जिनके पास है ROW_NUMBER() = 1:

WITH CTE AS (
    SELECT  *
           ,row_number() OVER(PARTITION BY word, num ORDER BY id) AS row_num
    FROM    dupes
)
SELECT  word, num, id 
FROM    cte
WHERE   row_num = 1
ORDER BY word, num;

/*
word|num|id|
----|---|--|
aaa |100| 1|
bbb |200| 2|
bbb |400| 4|
ccc |300| 3|
ddd |400| 7|
*/

6

सिर्फ इनर ज्वाइन का उपयोग करें क्योंकि समूह कई कॉलमों के साथ काम नहीं करेगा, जिसमें यह नहीं कहा जाएगा कि यह कुल मिलाकर फंक्शन नहीं है।

SELECT a.*
FROM yourtable a
INNER JOIN 
  (SELECT yourcolumn,
    MIN(id) as id
  FROM yourtable 
  GROUP BY yourcolumn
) AS b
  ON a.yourcolumn= b.yourcolumn
  AND a.id = b.id;

यह एक अलग सवाल का जवाब है, शायद एक जिसे सबसे महान-एन-प्रति-समूह के
a_horse_with_no_name

यह और डेव बेकर का समाधान एसओ प्रश्न के लिए सही समाधान हैं। इस समाधान का लाभ यह है कि यह केवल कुछ निर्दिष्ट विशिष्ट स्तंभों वाली पंक्तियों का चयन करने की अनुमति देता है और एक कॉलम MIN (आईडी) AS आईडी को कई निर्दिष्ट स्तंभों में से केवल एक का चयन करने के लिए परिभाषित किया जाना है।
जियोर्डानो

1

मुझे लगता है कि अगर मैं किसी कारण से DISTINCT का उपयोग नहीं कर सकता, तो GROUP BY काम करेगा।


1

अपने परिणाम में सभी कॉलम प्राप्त करने के लिए आपको कुछ इस प्रकार रखना होगा:

SELECT distinct a, Table.* FROM Table

यह जगह होगा एक प्रथम स्तंभ के रूप में और बाकी सभी अपनी परिभाषा के रूप में एक ही क्रम में स्तंभों की हो जाएगा। यह है, एक कॉलम दोहराया जाएगा।


1
क्या तुम इसके बारे में निश्चित हो? मैंने इसे w3schools पर आज़माया और यह
सेलेक्ट

@ सच में हाँ और यह वही है जो कहता है कि यह मेरे जवाब में क्या करेगा: /
htafoya

यह काम नहीं करेगा, आप इस तरह के अंतर के बाद * का चयन नहीं कर सकते (आपको 1064 त्रुटि मिलेगी - आपके SQL सिंटैक्स में त्रुटि)
tim.baker

@ मोहिनीखान अच्छी तरह से मैं यह भूल गया कि आपको तालिका का नाम लिखने की आवश्यकता है। किसी तरह जब मैंने इसे लिखा यह काम किया है, लेकिन मैं अभी परीक्षण किया है और यह तालिका नाम के बिना नहीं था *
htafoya

2
यह ठीक उसी तरह है जैसेselect distinct * from ...
a_horse_with_no_name

-4

से Eff_st चुनें (EFF_ST, ROW_NUMBER () से अधिक का चयन करें (पार्टी द्वारा eff_st) XYZ - ABC.CODE_DIM से

) जहाँ EY_ST द्वारा XYZ = 1 ऑर्डर पहली 5 पंक्ति में ही मिलेगा

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