web-dev-qa-db-fra.com

Comment sélectionner chaque ligne où la valeur de colonne n'est pas distincte

Je dois exécuter une instruction select qui renvoie toutes les lignes pour lesquelles la valeur d'une colonne n'est pas distincte (par exemple, EmailAddress).

Par exemple, si le tableau ressemble à celui ci-dessous:

CustomerName     EmailAddress
Aaron            [email protected]
Christy          [email protected]
Jason            [email protected]
Eric             [email protected]
John             [email protected]

J'ai besoin de la requête pour retourner:

Aaron            [email protected]
Christy          [email protected]
John             [email protected]

J'ai lu de nombreux articles et essayé différentes requêtes en vain. La requête qui, à mon avis, devrait fonctionner est ci-dessous. Quelqu'un peut-il suggérer une alternative ou me dire ce qui ne va pas avec ma requête?

select EmailAddress, CustomerName from Customers
group by EmailAddress, CustomerName
having COUNT(distinct(EmailAddress)) > 1
102
Grasshopper

C'est beaucoup plus rapide que la manière EXISTS:

SELECT [EmailAddress], [CustomerName] FROM [Customers] WHERE [EmailAddress] IN
  (SELECT [EmailAddress] FROM [Customers] GROUP BY [EmailAddress] HAVING COUNT(*) > 1)
190
Serj Sagan

La chose qui ne va pas avec votre requête est que vous regroupez par email et par nom, ce qui forme un groupe de chaque ensemble unique d’adresses et de noms combinés et par conséquent 

aaron and [email protected]
christy and [email protected]
john and [email protected]

sont traités comme 3 groupes différents plutôt que tous appartenant à un seul groupe.

Veuillez utiliser la requête ci-dessous:

select emailaddress,customername from customers where emailaddress in
(select emailaddress from customers group by emailaddress having count(*) > 1)
37
Seasoned

Que diriez-vous

SELECT EmailAddress, CustomerName FROM Customers a
WHERE Exists ( SELECT emailAddress FROM customers c WHERE a.customerName != c.customerName AND a.EmailAddress = c.EmailAddress)
10
Marc
select CustomerName,count(1) from Customers group by CustomerName having count(1) > 1
8
Nisar

Juste pour le plaisir, voici une autre façon:

;with counts as (
    select CustomerName, EmailAddress,
      count(*) over (partition by EmailAddress) as num
    from Customers
)
select CustomerName, EmailAddress
from counts
where num > 1
4
Chad

Plutôt que d'utiliser des sous-requêtes dans la condition où cela augmentera le temps de requête lorsque les enregistrements sont énormes.

Je suggérerais d'utiliser Inner Join comme meilleure option pour résoudre ce problème.

Considérant le même tableau cela pourrait donner le résultat

SELECT EmailAddress, CustomerName FROM Customers as a 
Inner Join Customers as b on a.CustomerName <> b.CustomerName and a.EmailAddress = b.EmailAddress

Pour des résultats encore meilleurs, je vous suggère d'utiliser CustomerID ou tout champ unique de votre table. La duplication de CustomerName est possible.

4
Naveen Kishan

Exemple de requête: 

SELECT [EmailAddress], [CustomerName] FROM [Customers] WHERE [EmailAddress] IN
  (SELECT [EmailAddress] FROM [Customers] GROUP BY [EmailAddress] HAVING COUNT(*) > 1);
0
HossamElmsry