查询从表中删除重复记录而不使用临时表?

时间:2010-08-07 10:53:07

标签: sql-server-2005

我想从表中删除重复记录而不使用临时表,怎么可能?

5 个答案:

答案 0 :(得分:4)

  1. 创建一个查询A,可以获得符合重复项的行
  2. 创建一个查询B,为您提供要保留的行
  3. 创建一个查询,删除A中但不在B中的所有行。
  4. 实施例

    假设一个名为table的表,其中一个名为id的自动增量ID列和一个名为name的列要删除双打。在每个名称中,您希望保留最旧的记录(ID最低的记录)。

    查询A看起来像是:

    SELECT * FROM table 
    WHERE name IN (SELECT name FROM table GROUP BY name HAVING COUNT(*) > 1)
    

    查询B将是:

    SELECT * FROM table 
    WHERE id IN (SELECT min(id) FROM table GROUP BY name)
    

    现在将它们组合起来形成删除查询:

    DELETE FROM table 
    WHERE name IN (SELECT name FROM table GROUP BY name HAVING COUNT(*) > 1)
    AND NOT id IN (SELECT min(id) FROM table GROUP BY name)
    

    在手边的示例中,您可以省略第一个查询,但是当事情变得更复杂时,这是一个很好的额外保护措施。

答案 1 :(得分:1)

你做不到。 完全重复记录(每个字段相等的记录)不能被一个删除,因为您无法在删除查询的Where子句中区分它们。
唯一的方法是执行select distinct查询以选择所有没有重复的行,然后将它们插入空表中。

如果您没有完全重复的记录,那么问题的表述不正确,并且您不希望删除重复的记录,因为没有任何记录。具有不完整的相等字段集的行不是重复的。在这种情况下,您可能希望删除某些字段相等的行,在这种情况下,如果某个字段或字段集不相等,则必须指定要离开的行。

答案 2 :(得分:0)

通过使用公用表表达式(CTE)可以毫无问题地执行此操作,您根本不需要使用任何临时表。如果删除是针对高流量表,请小心。删除大量数据可能会导致锁定和阻塞,也会导致转换日志。

注意:此代码是在没有任何测试的情况下编写的,但应该可以使用(SQL 2005及更高版本)。

/* Create test data with duplicates */
declare @TestTable Table (Col1 int)

insert into @TestTable

select 1 union all
select 1 union all
select 2 union all
select 3 union all
select 3 union all
select 4
;
/* Create CTE to number all duplicates (gives a running number to all identical values in Col1) */
with FindDupes as
(
Select Col1,ROW_NUMBER() over (partition by Col1 order by Col1) RN

from @TestTable
)
/* Delete the duplicates (anything that has a higher rownumber than one) */
Delete from FindDupes where RN>1
;

/* Select the remaining data from the table */
Select * from @TestTable

答案 3 :(得分:0)

/ *如果表有重复的行那么你可以使用这个查询* /

/ *你可以使用任何等级功能Row_Number(),Rank()和Dense_Rank()输出将是相同的* /

从员工E中删除   加入(    SELECT * FROM(       SELECT ROW_NUMBER()OVER(PARTITION BY Name ORDER BY ID)as RowNo,id,Employee的Name)X其中X.RowNo = 2)X On E.ID = E.ID

答案 4 :(得分:-1)

我认为此查询可以正常运行:

delete from table where id in (select count(*)c from table group by id having c > 1)