Selecione a instrução para encontrar duplicatas em determinados campos

Você pode me ajudar com instruções SQL para encontrar duplicatas em vários campos?

Por exemplo, no pseudo código:

select count(field1,field2,field3) from table where the combination of field1, field2, field3 occurs multiple times 

e da declaração acima, se houver várias ocorrências , gostaria de selecionar todos os registros, exceto o primeiro .

Para obter a lista de campos para os quais existem vários registros, você pode usar …

 select field1,field2,field3, count(*) from table_name group by field1,field2,field3 having count(*) > 1 

Verifique este link para mais informações sobre como excluir as linhas.

http://support.microsoft.com/kb/139444

Edit: Como os outros usuários mencionados, deve haver um critério para decidir como você define “primeiras linhas” antes de usar a abordagem no link acima. Com base nisso, você precisará usar uma cláusula order by e uma subconsulta, se necessário. Se você puder postar alguns dados de amostra, isso realmente ajudará.

Você menciona “o primeiro”, então presumo que você tenha algum tipo de pedido em seus dados. Vamos supor que seus dados sejam ordenados por algum ID campo.

Esse SQL deve obter as inputs duplicadas, exceto a primeira. Basicamente, ele seleciona todas as linhas para as quais outra linha possui (a) os mesmos campos e (b) existe um ID menor. O desempenho não será ótimo, mas poderá resolver o seu 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) 

Esta é uma solução divertida com o SQL Server 2005 que eu gosto. Vou supor que “para cada registro, exceto o primeiro”, você quer dizer que há outra coluna “id” que podemos usar para identificar qual linha é “a primeira”.

 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 

Para ver o valor duplicado

 with MYCTE as ( select row_number() over ( partition by name order by name) rown, * from tmptest ) select * from MYCTE where rown < =1 

Se você estiver usando o SQL Server 2005 ou posterior (e as marcações para sua pergunta indicam SQL Server 2008), você pode usar funções de sorting para retornar os registros duplicados após o primeiro se usar joins é menos desejável ou impraticável por algum motivo. O exemplo a seguir mostra isso em ação, onde também trabalha com valores nulos nas colunas examinadas.

 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 

Observe depois de executar este exemplo que o primeiro registro de cada “grupo” é excluído e que os registros com valores nulos são tratados corretamente.

Se você não tiver uma coluna disponível para solicitar os registros em um grupo, poderá usar as colunas de partição por como as colunas de ordem por.

 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