Pertanyaan Menemukan nilai duplikat dalam tabel SQL


Sangat mudah ditemukan duplicates dengan satu bidang:

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

Jadi jika kita punya meja

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

Kueri ini akan memberi kita John, Sam, Tom, Tom karena mereka semua memiliki yang sama email.

Namun, yang saya inginkan adalah mendapatkan duplikat dengan hal yang sama email dan name.

Artinya, saya ingin mendapatkan "Tom", "Tom".

Alasan saya membutuhkan ini: saya membuat kesalahan, dan diperbolehkan memasukkan duplikat name dan email nilai-nilai. Sekarang saya perlu hapus / ubah duplikat, jadi saya perlu menemukan mereka dulu.


1297
2018-04-07 18:17


asal


Jawaban:


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

Cukup kelompokkan pada kedua kolom.

Catatan: standar ANSI yang lama adalah memiliki semua kolom yang tidak diagregasi dalam GROUP BY tetapi ini telah berubah dengan ide "ketergantungan fungsional":

Dalam teori basis data relasional, ketergantungan fungsional adalah kendala antara dua set atribut dalam relasi dari database. Dengan kata lain, ketergantungan fungsional adalah kendala yang menggambarkan hubungan antara atribut dalam suatu relasi.

Dukungan tidak konsisten:


2121
2018-04-07 18:20



coba ini:

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

KELUARAN:

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

(2 row(s) affected)

jika Anda ingin ID dari dups menggunakan ini:

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

KELUARAN:

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

(4 row(s) affected)

untuk menghapus duplikat coba:

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

KELUARAN:

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

(4 row(s) affected)

273
2018-04-07 18:22



Coba ini:

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

89
2018-04-07 18:20



Jika Anda ingin menghapus duplikat, berikut ini cara yang lebih sederhana untuk melakukannya daripada harus menemukan baris genap / ganjil menjadi tiga sub-pilih:

SELECT id, name, email 
FROM users u, users u2
WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id

Dan untuk menghapus:

DELETE FROM users
WHERE id IN (
    SELECT id/*, name, email*/
    FROM users u, users u2
    WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
)

Jauh lebih mudah untuk membaca dan memahami IMHO

catatan: Satu-satunya masalah adalah Anda harus menjalankan permintaan hingga tidak ada baris yang dihapus, karena Anda hanya menghapus 1 dari setiap duplikat setiap kali


42
2018-03-14 14:22



Coba yang berikut ini:

SELECT * FROM
(
    SELECT Id, Name, Age, Comments, Row_Number() OVER(PARTITION BY Name, Age ORDER By Name)
        AS Rank 
        FROM Customers
) AS B WHERE Rank>1

30
2017-12-31 10:07



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

21
2017-07-22 07:12



Sedikit terlambat ke pesta, tetapi saya menemukan solusi yang sangat keren untuk menemukan semua ID duplikat:

SELECT GROUP_CONCAT( id )
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )

17
2017-11-17 10:21



coba kode ini

WITH CTE AS

( SELECT Id, Name, Age, Comments, RN = ROW_NUMBER()OVER(PARTITION BY Name,Age ORDER BY ccn)
FROM ccnmaster )
select * from CTE 

15
2017-09-13 04:03