मैं कई कॉलमों में डुप्लिकेट कैसे खोज सकता हूं?


98

इसलिए मैं नीचे इस sql कोड जैसा कुछ करना चाहता हूं:

select s.id, s.name,s.city 
from stuff s
group by s.name having count(where city and name are identical) > 1

निम्नलिखित उत्पादन करने के लिए, (लेकिन केवल नाम या केवल शहर के मिलान को अनदेखा करें, यह दोनों स्तंभों पर होना चाहिए):

id      name  city   
904834  jim   London  
904835  jim   London  
90145   Fred  Paris   
90132   Fred  Paris
90133   Fred  Paris

जवाबों:


137

दोहराए idजोड़े के लिए nameऔर city:

select s.id, t.* 
from [stuff] s
join (
    select name, city, count(*) as qty
    from [stuff]
    group by name, city
    having count(*) > 1
) t on s.name = t.name and s.city = t.city

ध्यान दें कि यदि कोई है nameया cityशामिल है null, तो वे बाहरी क्वेरी में रिपोर्ट किए जाने में विफल रहेंगे, लेकिन आंतरिक क्वेरी में मिलान किया जाएगा।
एडम पार्किन

3
यदि मानों में संभवतः nullतब तक हो सकता है (जब तक कि मैं कुछ याद नहीं कर रहा हूं) आपको इसे CROSS JOIN(पूर्ण कार्टेशियन उत्पाद) में बदलने की आवश्यकता है और फिर एक WHEREखंड जोड़ें जैसे:WHERE ((s.name = t.name) OR (s.name is null and t.name is null)) AND ((s.city = t.city) OR (s.city is null and t.city is null))
एडम पार्किं

56
 SELECT name, city, count(*) as qty 
 FROM stuff 
 GROUP BY name, city HAVING count(*)> 1

10

कुछ इस तरह से करेंगे ट्रिक प्रदर्शन के बारे में नहीं जानते, इसलिए कुछ परीक्षण करें।

select
  id, name, city
from
  [stuff] s
where
1 < (select count(*) from [stuff] i where i.city = s.city and i.name = s.name)

6

का उपयोग करते हुए count(*) over(partition by...)प्रदान करता है एक सरल और प्रभावी साधन अवांछित पुनरावृत्ति पता लगाने के लिए, जबकि भी सभी प्रभावित पंक्तियों और सभी चाहते थे कॉलम सूची:

SELECT
    t.*
FROM (
    SELECT
        s.*
      , COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty
    FROM stuff s
    ) t
WHERE t.qty > 1
ORDER BY t.name, t.city

जबकि अधिकांश हाल के RDBMS संस्करण count(*) over(partition by...) MySQL V 8.0 को "विंडो फ़ंक्शंस" के रूप में समर्थन करते हैं, जैसा कि नीचे देखा गया है (MySQL 8.0 में)

CREATE TABLE stuff(
   id   INTEGER  NOT NULL
  ,name VARCHAR(60) NOT NULL
  ,city VARCHAR(60) NOT NULL
);
INSERT INTO stuff(id,name,city) VALUES 
  (904834,'jim','London')
, (904835,'jim','London')
, (90145,'Fred','Paris')
, (90132,'Fred','Paris')
, (90133,'Fred','Paris')

, (923457,'Barney','New York') # not expected in result
;
SELECT
    t.*
FROM (
    SELECT
        s.*
      , COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty
    FROM stuff s
    ) t
WHERE t.qty > 1
ORDER BY t.name, t.city
    आईडी | नाम | शहर | मात्रा
-----: | : --- | : ----- | -:
 90145 | फ्रेड | पेरिस | 3
 90132 | फ्रेड | पेरिस | 3
 90133 | फ्रेड | पेरिस | 3
904834 | जिम् | लंदन | 2
904835 | जिम् | लंदन | 2

db <> फिडल यहां

विंडो फ़ंक्शन। MySQL अब विंडो फ़ंक्शंस का समर्थन करता है, जो क्वेरी से प्रत्येक पंक्ति के लिए, उस पंक्ति से संबंधित पंक्तियों का उपयोग करके गणना करता है। इनमें RANK (), LAG (), और NTILE () जैसे फ़ंक्शन शामिल हैं। इसके अलावा, कई मौजूदा कुल कार्यों को अब विंडो फ़ंक्शन के रूप में उपयोग किया जा सकता है; उदाहरण के लिए, SUM () और AVG ()। अधिक जानकारी के लिए, खंड 12.21, “विंडो फ़ंक्शंस” देखें


3

इस पद पर खेल के लिए थोड़ी देर हो गई, लेकिन मुझे यह तरीका काफी लचीला / कुशल लगा

select 
    s1.id
    ,s1.name
    ,s1.city 
from 
    stuff s1
    ,stuff s2
Where
    s1.id <> s2.id
    and s1.name = s2.name
    and s1.city = s2.city

2

आपको सामान और मैच के नाम और शहर से जुड़ना होगा। फिर गिनती करके समूह बनाएं।

select 
   s.id, s.name, s.city 
from stuff s join stuff p ON (
   s.name = p.city OR s.city = p.name
)
group by s.name having count(s.name) > 1

SQL सर्वर में विफल रहता है: सभी गैर-समुच्चय स्तंभ GROUP BY
gbn

0

70 कॉलम और केवल 4 डुप्लिकेट का प्रतिनिधित्व करने वाली एक मेज़िंग टेबल को देखते हुए, यह कोड आपत्तिजनक कॉलम लौटाएगा:

SELECT 
    COUNT(*)
    ,LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime))
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
FROM Staging.dbo.Stage S
GROUP BY 
    LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime))
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
HAVING COUNT(*) > 1

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