Frage Doppelte Werte in einer SQL-Tabelle finden


Es ist leicht zu finden duplicates mit einem Feld:

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

Also wenn wir einen Tisch 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 wird uns geben John, Sam, Tom, Tom weil sie alle gleich sind email.

Was ich will, ist jedoch, Duplikate mit dem gleichen zu bekommen email und name.

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

Der Grund, warum ich das brauche: Ich habe einen Fehler gemacht und erlaubt, ein Duplikat einzufügen name und email Werte. Jetzt muss ich entfernen / ändern die Duplikate, also muss ich finden sie zuerst.


1297
2018-04-07 18:17


Ursprung


Antworten:


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

Gruppieren Sie einfach auf beiden Spalten.

Hinweis: Der ältere ANSI-Standard besteht darin, alle nicht aggregierten Spalten in der GROUP BY zu haben, aber dies hat sich mit der Idee geändert "funktionale Abhängigkeit":

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

Support ist nicht konsistent:


2121
2018-04-07 18:20



Versuche 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

AUSGABE:

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

(2 row(s) affected)

Wenn Sie möchten, dass die IDs der Dups dies verwenden:

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

AUSGABE:

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 Folgendes:

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

AUSGABE:

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



Versuche dies:

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

89
2018-04-07 18:20



Wenn Sie die Duplikate löschen möchten, ist dies ein viel einfacherer Weg, als gerade / ungerade Zeilen in eine dreifache Unterauswahl zu finden:

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

Und so zu löschen:

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
)

Viel einfacher zu lesen und zu verstehen, IMHO

Hinweis: Das einzige Problem besteht darin, dass Sie die Anforderung ausführen müssen, bis keine Zeilen mehr gelöscht werden, da Sie jedes Mal nur 1 von jedem Duplikat löschen


42
2018-03-14 14:22



Versuche Folgendes:

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



Ein wenig spät auf die Party, aber ich fand eine wirklich coole Möglichkeit, alle doppelten IDs zu finden:

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

17
2017-11-17 10:21



Probieren Sie diesen Code aus

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