如何在SQL中比较两个表并删除重复行?

6

我有两个表格,需要从第一个表格中删除行,如果第二个表格中存在一行的完全副本。

请问有人能提供在MSSQL服务器上如何实现这个功能的示例吗?

5个回答

9

好的,在某些时候,您将不得不检查所有列 - 最好加入...

DELETE a
FROM a  -- first table
INNER JOIN b -- second table
      ON b.ID = a.ID
      AND b.Name = a.Name
      AND b.Foo = a.Foo
      AND b.Bar = a.Bar

这样应该就可以了...还有一个CHECKSUM(*),但这只是起到辅助作用 - 你仍然需要检查实际值以排除哈希冲突。


5
只要没有任何一列包含空值,这个方法就能够很好地运作。但是一旦有空值出现,你就必须使用复杂的条件,比如对于每个可空列都要加入类似于(a.Name = b.Name OR (a.Name IS NULL AND b.Name IS NULL))这样的条件。这也是避免使用空值的另一个原因。 - Jonathan Leffler
@Marc Gravell,如果视图中存在表a和表b。那么我该如何删除重复行并保留原始行?我已经在[http://stackoverflow.com/questions/32065340/sql-server-2008-r2-delete-duplicate-rows-from-tables-containing-in-view/32065972?noredirect=1#comment52032907_32065972]上发布了这种情况的问题。 - MAK
使用INTERSECT和EXCEPT(参见其他答案)进行这些类型的操作可以避免NULL问题。http://sqlblog.com/blogs/paul_white/archive/2011/06/22/undocumented-query-plans-equality-comparisons.aspx - rpggio

8

如果你正在使用 SQL Server 2005,你可以使用 intersect

delete * from table1 intersect select * from table2

1

我认为下面的伪代码可以实现它..

DELETE FirstTable, SecondTable
FROM FirstTable
FULL OUTER JOIN SecondTable
ON FirstTable.Field1 = SecondTable.Field1
... continue for all fields
WHERE FirstTable.Field1 IS NOT NULL
AND SecondTable.Field1 IS NOT NULL

Chris的INTERSECT帖子更加优雅,我将来会使用它,而不是编写所有外部连接条件 :)


0

试试这个:

DELETE t1 FROM t1 INNER JOIN t2 ON t1.name = t2.name WHERE t1.id = t2.id

0

我会尝试使用DISTINCT查询,并将两个表进行合并。

你可以使用脚本语言如asp/php来格式化输出为一系列的插入语句,以重新构建包含唯一数据的表格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接