如何删除重复的基于行的非主键列

时间:2014-10-30 00:57:26

标签: mysql sql sql-server tsql

所以我有一个表架构设置: http://sqlfiddle.com/#!6/62d3e/1/0

我有几行按字段,fieldtypeid,fieldalias列重复。我需要删除由这3列复制的所有行,但是对于“somevalue”列具有空值。

最简单的方法是什么?我试图做一个MERGE语句,但这不起作用,因为merge捕获了重复项。

DECLARE @A TABLE(Id INT, field NVARCHAR(50), fieldType INT, fieldalias NVARCHAR(50), ForDelete BIT)
 DECLARE @B TABLE(Id INT, field NVARCHAR(50), fieldTypeId INT, fieldalias NVARCHAR(50), ForDelete BIT)

 INSERT INTO @A
 SELECT DISTINCT c.Id, c.field, c.fieldTypeId, c.fieldalias,0
 FROM DuplicateValues c
 WHERE c.somevalue IS NOT NULL

 INSERT INTO @B
 SELECT DISTINCT c.Id, c.field, c.fieldTypeId, c.fieldalias,0
 FROM DuplicateValues c
 WHERE c.somevalue IS NULL

 declare @T table(Id int, ForDelete BIT, Act varchar(10))


 MERGE @B AS B
 USING @A AS A
 ON A.fieldTypeId = B.fieldTypeId AND A.field = B.field AND A.fieldalias = B.fieldalias
 WHEN MATCHED THEN UPDATE SET B.ForDelete = 1
 WHEN NOT MATCHED THEN INSERT (Id, field, fieldTypeId, fieldalias, ForDelete) VALUES(A.Id, A.field,A.fieldTypeId, A.fieldalias, 1)
 OUTPUT INSERTED.Id, INSERTED.ForDelete, $ACTION INTO @T;


 SELECT * FROM @T

3 个答案:

答案 0 :(得分:2)

根据您提供的Fiddle架构,您可以使用以下查询来实现相同的目标。查看修改过的小提琴http://sqlfiddle.com/#!6/0f201/1

delete from DuplicateValues
where FIELD in(
  select FIELD from DuplicateValues
  group by field, fieldtypeId, fieldalias
  having count(*) > 1
  )
and somevalue is null

此处group by .. having count(*) > 1将提供已复制的所有FIELDS

答案 1 :(得分:1)

在cte中使用窗口函数可以找到重复项。试试这个

;WITH cte 
     AS (SELECT Row_number() OVER(partition BY field, fieldtypeid, fieldalias ORDER BY id) rn, 
                * 
         FROM   duplicatevalues) 
DELETE A 
FROM   duplicatevalues a 
       JOIN cte b 
         ON a.id = b.id 
WHERE  rn > 1

答案 2 :(得分:0)

您可以使用Row_number()函数,如:

;WITH cte 
 AS (SELECT Row_number() OVER(partition BY field, fieldtypeid, fieldalias ORDER BY id) Row, 
            * 
     FROM   duplicatevalues) 
 DELETE From cte WHERE  Row> 1