SQL tablosunda yinelenen değerleri bulma

Tek bir alanla kopyaları bulmak kolaydır:

SELECT name, COUNT(email) 
FROM users
GROUP BY email
HAVING COUNT(email) > 1

Yani eğer bir tablomuz varsa

ID   NAME   EMAIL
1    John   asd@asd.com
2    Sam    asd@asd.com
3    Tom    asd@asd.com
4    Bob    bob@asd.com
5    Tom    asd@asd.com

Bu sorgu bize John, Sam, Tom, Tom'u verecektir çünkü hepsi aynı emaile sahiptir.

Ancak, istediğim şey aynı email ve name ile kopyaları almak.

Yani, "Tom", "Tom"'u almak istiyorum.

Buna ihtiyacım olmasının sebebi: Bir hata yaptım ve yinelenen name ve email değerlerinin eklenmesine izin verdim. Şimdi kopyaları kaldırmam/değiştirmem gerekiyor, bu yüzden önce onları bulmam gerekiyor.

Çözüm
SELECT
    name, email, COUNT(*)
FROM
    users
GROUP BY
    name, email
HAVING 
    COUNT(*) > 1

Her iki sütunda da gruplama yapmanız yeterlidir.

Not: Eski ANSI standardı, GROUP BY içinde tüm toplanmamış sütunların bulunmasıdır, ancak bu "işlevsel bağımlılık" fikriyle değişmiştir:

İlişkisel veritabanı teorisinde, işlevsel bağımlılık, bir veritabanındaki bir ilişkideki iki nitelik kümesi arasındaki bir kısıtlamadır. Başka bir deyişle, fonksiyonel bağımlılık, bir ilişkideki nitelikler arasındaki ilişkiyi tanımlayan bir kısıtlamadır.

Destek tutarlı değildir:

Yorumlar (10)

Bunu dene:

declare @YourTable table (id int, name varchar(10), email varchar(50))

INSERT @YourTable VALUES (1,'John','John-email')
INSERT @YourTable VALUES (2,'John','John-email')
INSERT @YourTable VALUES (3,'fred','John-email')
INSERT @YourTable VALUES (4,'fred','fred-email')
INSERT @YourTable VALUES (5,'sam','sam-email')
INSERT @YourTable VALUES (6,'sam','sam-email')

SELECT
    name,email, COUNT(*) AS CountOf
    FROM @YourTable
    GROUP BY name,email
    HAVING COUNT(*)>1

ÇIKIŞ:

name       email       CountOf
---------- ----------- -----------
John       John-email  2
sam        sam-email   2

(2 row(s) affected)

eğer yedeklerin ID'lerini istiyorsanız bunu kullanın:

SELECT
    y.id,y.name,y.email
    FROM @YourTable y
        INNER JOIN (SELECT
                        name,email, COUNT(*) AS CountOf
                        FROM @YourTable
                        GROUP BY name,email
                        HAVING COUNT(*)>1
                    ) dt ON y.name=dt.name AND y.email=dt.email

ÇIKIŞ:

id          name       email
----------- ---------- ------------
1           John       John-email
2           John       John-email
5           sam        sam-email
6           sam        sam-email

(4 row(s) affected)

kopyaları silmek için deneyin:

DELETE d
    FROM @YourTable d
        INNER JOIN (SELECT
                        y.id,y.name,y.email,ROW_NUMBER() OVER(PARTITION BY y.name,y.email ORDER BY y.name,y.email,y.id) AS RowRank
                        FROM @YourTable y
                            INNER JOIN (SELECT
                                            name,email, COUNT(*) AS CountOf
                                            FROM @YourTable
                                            GROUP BY name,email
                                            HAVING COUNT(*)>1
                                        ) dt ON y.name=dt.name AND y.email=dt.email
                   ) dt2 ON d.id=dt2.id
        WHERE dt2.RowRank!=1
SELECT * FROM @YourTable

ÇIKIŞ:

id          name       email
----------- ---------- --------------
1           John       John-email
3           fred       John-email
4           fred       fred-email
5           sam        sam-email

(4 row(s) affected)
Yorumlar (0)

Bunu dene:

SELECT name, email
FROM users
GROUP BY name, email
HAVING ( COUNT(*) > 1 )
Yorumlar (0)