2012-03-24 4 views
36

Sto convalidando una tabella che contiene dati a livello di transazione di un sito eCommerce e trova gli errori esatti.Trova record duplicati in una tabella utilizzando SQL Server

Desidero che il vostro aiuto trovi i record duplicati in una tabella a 50 colonne su SQL Server.

Suppongo che la mia è la:

OrderNo shoppername amountpayed city Item  
1  Sam   10   A Iphone 
1  Sam   10   A Iphone--->>Duplication to be detected 
1  Sam   5   A Ipod 
2  John  20   B Macbook 
3  John  25   B Macbookair 
4  Jack  5   A Ipod 

Supponiamo che io uso la domanda sotto:

Select shoppername,count(*) as cnt 
from dbo.sales 
having count(*) > 1 
group by shoppername 

tornerà me

Sam 2 
John 2 

Ma non voglio trovare duplicare solo oltre 1 o 2 colonne. Voglio trovare il duplicato su tutte le colonne insieme nei miei dati. Voglio il risultato come:

1  Sam   10   A Iphone 

risposta

3

Basta aggiungere tutti i campi alla query e ricordarsi di aggiungerli a Raggruppa come pure.

Select shoppername, a, b, amountpayed, item, count(*) as cnt 
from dbo.sales 
group by shoppername, a, b, amountpayed, item 
having count(*) > 1 
+1

ho 50 campi. Quindi non c'è modo in cui senza scrivere i nomi individuali di tutti i campi posso trovare i record duplicati !! – Matthew

+5

Fare clic con il tasto destro del mouse sulla tabella, selezionare: Tabella degli script come >> Selezionare per >> Finestra Nuovo editor di query. Ora hai la tua lista SELECT, copia e incolla nella tua sezione GROUP BY. – JerryOL

35
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as cnt 
FROM dbo.sales 
GROUP BY OrderNo, shoppername, amountPayed, city, item 
HAVING COUNT(*) > 1 
56
with x as (select *,rn = row_number() 
      over(PARTITION BY OrderNo,item order by OrderNo) 
      from #temp1) 

select * from x 
where rn > 1 

è possibile rimuovere i duplicati sostituendo selezionare dichiarazione

delete x where rn > 1 
+0

Grande. Sapevo di questo in Oracle, ma non sapevo che fosse possibile anche nel server SQL. – GolezTrol

+0

Ottima risposta. – HShbib

+1

Per chiunque fosse curioso, questo è come lo scriverei in Oracle: 'con x come (selezionare t.*, Row_number() su (PARTITION BY OrderNo, per voce da OrderNo) come rn da t_dcf t) select * from x dove rn> 1; ' – Juan

1

Prova a modificare la

SELECT MAX(shoppername), COUNT(*) AS cnt 
FROM dbo.sales 
GROUP BY CHECKSUM(*) 
HAVING COUNT(*) > 1 

Leggi sulla funzione CHECKSUM prima, come ci possono essere duplicati.

4
SQL> SELECT JOB,COUNT(JOB) FROM EMP GROUP BY JOB; 

JOB  COUNT(JOB) 
--------- ---------- 
ANALYST   2 
CLERK    4 
MANAGER   3 
PRESIDENT   1 
SALESMAN   4 
-2

Select * da dbo.sales gruppo da shoppername avendo (count (Voce)> 1)

+0

Prova questo funzionerà – Mahaveer

+0

che Will ** non ** lavoro. Si otterrà un 'colonna non è valida nell'elenco di selezione perché non è contenuta in entrambi una funzione di aggregazione o GROUP BY errore di clausola di – kkuilla

2

Per ottenere l'elenco dei più record utilizzare il comando seguente

select field1,field2,field3, count(*) 
    from table_name 
    group by field1,field2,field3 
    having count(*) > 1 
0
with x as (
select shoppername,count(shoppername) 
       from sales 
       having count(shoppername)>1 
      group by shoppername) 
select t.* from x,win_gp_pin1510 t 
where x.shoppername=t.shoppername 
order by t.shoppername 
-2

Selezionare EventID, contare () come cnt da dbo.EventInstances gruppo da EventID avendo count ()> 1

-2

Il seguente codice è in esecuzione:

SELECT abnno, COUNT(abnno) 
FROM tbl_Name 
GROUP BY abnno 
HAVING (COUNT(abnno) > 1) 
+0

Si prega di includere la formattazione corretta nella sua risposta, e anche spiegare ciò che fa per renderlo più chiaro. –

0

Prima di tutto, dubito che il risultato non è preciso? Sembra che ci siano tre "Sam" dal tavolo originale. Ma non è fondamentale per la domanda.

Poi arriviamo per la domanda stessa. In base alla tabella, il modo migliore per mostrare il valore duplicato è utilizzare la clausola count(*) e Group by.La query sarebbe simile a questa

SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as RepeatTimes FROM dbo.sales GROUP BY OrderNo, shoppername, amountPayed, city, item HAVING COUNT(*) > 1

La ragione è che tutte le colonne insieme dal vostro tavolo identificato in modo univoco ogni record, il che significa che le registrazioni saranno considerate come duplicati solo quando tutti i valori di ogni colonna sono esattamente gli stessi , anche tu vuoi mostrare tutti i campi per i record duplicati, quindi lo group by non mancherà nessuna colonna, altrimenti sì, perché puoi solo le colonne select che partecipano alla clausola 'group by'.

Ora vorrei darvi qualsiasi esempio per With...Row_Number()Over(...), che utilizza l'espressione della tabella insieme alla funzione Row_Number.

Supponiamo di avere un tavolo quasi uguale ma con una colonna in più denominata Data di spedizione e il valore potrebbe cambiare anche se il resto è lo stesso. Eccolo:

OrderNo shoppername amountpayed city Item Shipping Date
1 Sam 10 A Iphone 2016-01-01 1 Sam 10 A Iphone 2016-02-02 1 Sam 5 A Ipod 2016-03-03 2 John 20 B Macbook 2016-04-04 3 John 25 B Macbookair 2016-05-05 4 Jack 5 A Ipod 2016-06-06

noti che fila # 2 non è un duplicato se ancora prende tutte le colonne come unità. Ma cosa succede se si desidera trattarli come duplicati anche in questo caso? Si dovrebbe usare With...Row_Number()Over(...), e la query sarebbe simile a questa:

WITH TABLEEXPRESSION AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier) --if you consider the one with late shipping date as the duplicate FROM dbo.sales) SELECT * FROM TABLEEXPRESSION WHERE Identifier !=1 --or use '>1'

La query sopra darà seguito insieme con data di spedizione, per esempio:

OrderNo shoppername amountpayed city Item Shipping Date Identifier 1 Sam 10 A Iphone 2016-02-02 2

Nota questo è diverso da quello con 2016-01-01, e il motivo per cui 2016-02-02 è stato filtrato è PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier, e la data di spedizione NON è una delle colonne che devono essere prese in considerazione per i record duplicati, il che significa che con 2016-02-02 potrebbe ancora essere perfetto risultato per la tua domanda.

Ora riassumere po ', utilizzando count(*) e Group by clausola insieme è la scelta migliore quando si desidera solo per mostrare tutte le colonne da Group by clausola come risultato, altrimenti vi perderete le colonne che non partecipano group by.

Mentre per With...Row_Number()Over(...), è adatto in ogni scenario in cui si desidera trovare record duplicati, tuttavia, è un po 'complicato scrivere la query e un po' troppo ingegnerizzato rispetto al precedente.

Se lo scopo è eliminare i record duplicati dalla tabella, è necessario utilizzare lo WITH...ROW_NUMBER()OVER(...)...DELETE FROM...WHERE successivo.

Spero che questo aiuti!

0

Prova questa

with T1 AS 
(
SELECT LASTNAME, COUNT(1) AS 'COUNT' FROM Employees GROUP BY LastName HAVING COUNT(1) > 1 
) 
SELECT E.*,T1.[COUNT] FROM Employees E INNER JOIN T1 ON T1.LastName = E.LastName