Question Trouver des valeurs en double dans une table SQL


C'est facile à trouver duplicates avec un champ:

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

Donc, si nous avons une table

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

Cette requête nous donnera John, Sam, Tom, Tom parce qu'ils ont tous le même email.

Cependant, ce que je veux, c'est obtenir des doublons avec le même email et name.

C'est, je veux obtenir "Tom", "Tom".

La raison pour laquelle j'ai besoin de cela: j'ai fait une erreur, et permis d'insérer en double name et email valeurs. Maintenant j'ai besoin de enlever / changer les doublons, donc je dois trouver eux en premier.


1297
2018-04-07 18:17


origine


Réponses:


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

Simplement grouper sur les deux colonnes.

Remarque: l'ancienne norme ANSI doit avoir toutes les colonnes non agrégées dans le groupe BY, mais cela a changé avec l'idée de "dépendance fonctionnelle":

Dans la théorie des bases de données relationnelles, une dépendance fonctionnelle est une contrainte entre deux ensembles d'attributs dans une relation d'une base de données. En d'autres termes, la dépendance fonctionnelle est une contrainte qui décrit la relation entre les attributs d'une relation.

Le support n'est pas cohérent:


2121
2018-04-07 18:20



essaye ça:

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

SORTIE:

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

(2 row(s) affected)

Si vous voulez que les ID des dups utilisent ceci:

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

SORTIE:

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

(4 row(s) affected)

Pour supprimer les doublons, essayez:

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

SORTIE:

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



Essaye ça:

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

89
2018-04-07 18:20



Si vous voulez supprimer les doublons, voici une façon beaucoup plus simple de le faire que de trouver des lignes paires / impaires dans un triple sous-select:

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

Et donc pour supprimer:

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
)

Beaucoup plus facile à lire et à comprendre à mon humble avis

Remarque: Le seul problème est que vous devez exécuter la requête jusqu'à ce qu'il n'y ait plus de lignes supprimées, puisque vous supprimez seulement 1 de chaque copie à chaque fois


42
2018-03-14 14:22



Essayez ce qui suit:

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



Un peu en retard à la fête, mais j'ai trouvé une solution de rechange vraiment cool pour trouver tous les ID en double:

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

17
2017-11-17 10:21



essayez ce code

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



Dans le cas où vous travaillez avec Oracle, ce serait préférable:

create table my_users(id number, name varchar2(100), email varchar2(100));

insert into my_users values (1, 'John', 'asd@asd.com');
insert into my_users values (2, 'Sam', 'asd@asd.com');
insert into my_users values (3, 'Tom', 'asd@asd.com');
insert into my_users values (4, 'Bob', 'bob@asd.com');
insert into my_users values (5, 'Tom', 'asd@asd.com');

commit;

select *
  from my_users
 where rowid not in (select min(rowid) from my_users group by name, email);

13
2018-06-16 08:50



Ceci sélectionne / supprime tous les enregistrements en double sauf un enregistrement de chaque groupe de doublons. Ainsi, la suppression laisse tous les enregistrements uniques + un enregistrement de chaque groupe des doublons.

Sélectionnez les doublons:

SELECT *
FROM table
WHERE
    id NOT IN (
        SELECT MIN(id)
        FROM table
        GROUP BY column1, column2
);

Supprimer les doublons:

DELETE FROM table
WHERE
    id NOT IN (
        SELECT MIN(id)
        FROM table
        GROUP BY column1, column2
);

Soyez conscient des quantités plus importantes d'enregistrements, cela peut entraîner des problèmes de performances. 


11
2018-02-22 15:02



select id,name,COUNT(*) from India group by Id,Name having COUNT(*)>1

8
2017-09-12 18:18