Suche nach doppelten Werten in einer SQL-Tabelle

Es ist einfach, mit einem Feld Duplikate zu finden:

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

Wenn wir also eine Tabelle haben

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

Diese Abfrage liefert uns John, Sam, Tom, Tom, weil sie alle die gleiche E-Mail haben.

Was ich jedoch möchte, ist, Duplikate mit derselben "E-Mail" und "Name" zu erhalten.

Das heißt, ich möchte "Tom", "Tom" erhalten.

Der Grund, warum ich das brauche: Ich habe einen Fehler gemacht und erlaubt, doppelte Werte für Name und E-Mail einzufügen. Jetzt muss ich die Duplikate entfernen/ändern, also muss ich sie zuerst finden.

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

Gruppieren Sie einfach auf beiden Spalten.

Hinweis: Der ältere ANSI-Standard sieht vor, dass alle nicht aggregierten Spalten im GROUP BY enthalten sind, doch hat sich dies mit dem Konzept der "funktionalen Abhängigkeit" geändert:

In der relationalen Datenbanktheorie ist eine funktionale Abhängigkeit eine Einschränkung zwischen zwei Attributgruppen in einer Beziehung einer Datenbank. Mit anderen Worten, die funktionale Abhängigkeit ist eine Einschränkung, die die Beziehung zwischen Attributen in einer Beziehung beschreibt.

Die Unterstützung ist nicht konsistent:

Kommentare (10)

Versuchen Sie dies:

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

OUTPUT:

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

(2 row(s) affected)

wenn Sie die IDs der Dups haben wollen, verwenden Sie dies:

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

OUTPUT:

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

(4 row(s) affected)

um die Duplikate zu löschen, versuchen Sie:

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

OUTPUT:

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

(4 row(s) affected)
Kommentare (0)

Versuchen Sie dies:

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