2012-10-30 14 views
77

Devo eseguire un'istruzione select che restituisca tutte le righe in cui il valore di una colonna non è distinto (ad esempio EmailAddress).Come selezionare ogni riga dove NON è distinto il valore della colonna

Ad esempio, se la tabella si presenta come di seguito:

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

ho bisogno della query per restituire:

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

Ho letto molti post e ha cercato query diverse inutilmente. La query che credo dovrebbe funzionare è sotto. Qualcuno può suggerire un'alternativa o dirmi cosa potrebbe essere sbagliato nella mia domanda?

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

risposta

139

Questo è significativamente più veloce rispetto al EXISTS modo:

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

Come su

SELECT EmailAddress, CustomerName FROM Customers a 
WHERE Exists (SELECT emailAddress FROM customers c WHERE a.customerName != c.customerName AND a.EmailAddress = c.EmailAddress) 
4

Solo per divertimento, ecco un altro modo:

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

+1 per CTE versione Non dovremmo ripeterci nel codice, perché ripeterci in SQL se non dobbiamo più. – yzorg

+0

Io uso _count per la colonna count (oltre a num). Uso costantemente il carattere di sottolineatura quando le colonne si scontrano con parole chiave SQL come _default, _type, _sum, ecc. – yzorg

23

La cosa che non è corretto con la query è che si esegue il raggruppamento per e-mail e il nome, che forma un gruppo di ogni set unico di email e nome combinati insieme e quindi

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

vengono considerati come 3 gruppi diversi, ma tutti appartengono a 1 singolo gruppo.

Si prega di utilizzare la query come indicato di seguito:

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

Mi piace che tu abbia incluso anche una spiegazione su cosa c'è di sbagliato nella query originale, a differenza della risposta accettata. –

6
select CustomerName,count(1) from Customers group by CustomerName having count(1) > 1 
+0

miglioramento minore per mostrare il conteggio come "dups": selezionare CustomerName, count (1) come duplicati dal gruppo Clienti per CustomerName che ha il conteggio (1)> 1' – DynamicDan

-1

Beh c'è un leggero cambiamento per trovare le righe non distinti ..

SELEZIONA Indirizzo Email, Nome cliente FROM Clienti DOVE EmailAddress NON IN (SELECT EmailAddress FROM Customers GROUP BY EmailAddress CONTEGGIO CHE HA (*)> 1)

0

Invece di utilizzare le query sub in cui condizione che aumenterà il tempo di query in cui documenti sono in enormi.

Vorrei suggerire di utilizzare Inner Join come opzione migliore per questo problema.

Considerando stesso tavolo questo potrebbe dare il risultato

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

Per ottenere risultati ancora migliori vorrei suggerire di utilizzare CustomerID o qualsiasi campo unico del vostro tavolo. È possibile la duplicazione di CustomerName.

Problemi correlati