Puoi aiutarmi con le istruzioni SQL per trovare duplicati su più campi?
Ad esempio, in pseudo codice:
select count(field1,field2,field3)
from table
where the combination of field1, field2, field3 occurs multiple times
e dalla dichiarazione precedente se ci sono più occorrenze Vorrei selezionare ogni record tranne il primo .
Per ottenere l'elenco dei campi per i quali esistono più record, puoi utilizzare ..
select field1,field2,field3, count(*)
from table_name
group by field1,field2,field3
having count(*) > 1
Controlla questo link per maggiori informazioni su come eliminare le righe.
http://support.Microsoft.com/kb/139444
Modifica: come menzionato dagli altri utenti, dovrebbe esserci un criterio per decidere come definire "prime righe" prima di utilizzare l'approccio nel link sopra. Sulla base di questo dovrai usare una clausola order by e una sub-query, se necessario. Se puoi pubblicare alcuni dati di esempio, sarebbe davvero d'aiuto.
Lei cita "il primo", quindi presumo che tu abbia qualche tipo di ordinamento sui tuoi dati. Supponiamo che i tuoi dati siano ordinati da qualche campo ID
.
Questo SQL dovrebbe ottenere le voci duplicate tranne per il primo. Fondamentalmente seleziona tutte le righe per cui un'altra riga con (a) gli stessi campi e (b) esiste un ID inferiore. Le prestazioni non saranno grandi, ma potrebbero risolvere il tuo problema.
SELECT A.ID, A.field1, A.field2, A.field3
FROM myTable A
WHERE EXISTS (SELECT B.ID
FROM myTable B
WHERE B.field1 = A.field1
AND B.field2 = A.field2
AND B.field3 = A.field3
AND B.ID < A.ID)
Questa è una soluzione divertente con SQL Server 2005 che mi piace. Presumo che "per ogni record, tranne per il primo", intendi che esiste un'altra colonna "id" che possiamo usare per identificare quale riga è "prima".
SELECT id
, field1
, field2
, field3
FROM
(
SELECT id
, field1
, field2
, field3
, RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
FROM table_name
) a
WHERE [rank] > 1
Per vedere il valore duplicato
with MYCTE as (
select row_number() over ( partition by name order by name) rown, * from tmptest
)
select * from MYCTE where rown <=1
Se si utilizza SQL Server 2005 o versione successiva (e i tag per la domanda indicano SQL Server 2008), è possibile utilizzare le funzioni di classifica per restituire i record duplicati dopo il primo se l'utilizzo di join è meno desiderabile o poco pratico per qualche motivo. L'esempio seguente mostra questo in azione, dove funziona anche con valori null nelle colonne esaminate.
create table Table1 (
Field1 int,
Field2 int,
Field3 int,
Field4 int
)
insert Table1
values (1,1,1,1)
, (1,1,1,2)
, (1,1,1,3)
, (2,2,2,1)
, (3,3,3,1)
, (3,3,3,2)
, (null, null, 2, 1)
, (null, null, 2, 3)
select *
from (select Field1
, Field2
, Field3
, Field4
, row_number() over (partition by Field1
, Field2
, Field3
order by Field4) as occurrence
from Table1) x
where occurrence > 1
Si noti dopo aver eseguito questo esempio che il primo record di ogni "gruppo" è escluso e che i record con valori null vengono gestiti correttamente.
Se non si dispone di una colonna disponibile per ordinare i record all'interno di un gruppo, è possibile utilizzare le colonne partition-by come colonne order-by.
CREATE TABLE #tmp
(
sizeId Varchar(MAX)
)
INSERT #tmp
VALUES ('44'),
('44,45,46'),
('44,45,46'),
('44,45,46'),
('44,45,46'),
('44,45,46'),
('44,45,46')
SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)
SELECT @SqlStr = STUFF((SELECT ',' + sizeId
FROM #tmp
ORDER BY sizeId
FOR XML PATH('')), 1, 1, '')
SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
FROM dbo.Split(@SqlStr,',')
group by items
having count(*) > 1
)K
ORDER BY K.Occurrence DESC
prova questa query per avere un conteggio separato di ciascuna istruzione SELECT:
select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1