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 [email protected]
2 Sam [email protected]
3 Tom [email protected]
4 Bob [email protected]
5 Tom [email protected]
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.
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:
sql_mode=only_full_group_by
: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)
Versuchen Sie dies:
SELECT name, email
FROM users
GROUP BY name, email
HAVING ( COUNT(*) > 1 )