【问题标题】:Remove duplicate rows删除重复行
【发布时间】:2012-05-31 06:24:06
【问题描述】:

我需要删除所有重复的行:

t1
--------------------
col1    col2    col3
1       a       b
2       a       c
3       a       b

在本例中,1 和 3 是重复的。我需要将两者都插入另一个表,然后从当前表中删除。

t1
--------------------
col1    col2    col3
1       a       c

t2
--------------------
col1    col2    col3
1       a       b
2       a       b

最好的方法是什么?

编辑

我应该提供更多信息。 t1 是一个包含导入行的临时表。有 4 个字段可以唯一标识一条记录,每行还有 20 多个字段。如果有重复,则需要将它们插入到不同的表中以供查看。因此,我认为不需要保留身份值,因为一旦将其插入系统中,临时表中的值将不再有用。

【问题讨论】:

  • 在您的示例中,t2 的 col1 是否应该保留 t1 的值(即第二行有错字,“2”应该是“3”)?
  • @Clark - 已更新以包含更多信息。

标签: sql-server-2008 duplicate-removal


【解决方案1】:

以下代码对于删除重复记录很有用。该表必须有标识列,用于标识重复记录。示例中的表具有 ID 作为标识列,具有重复数据的列是 DuplicateColumn1、DuplicateColumn2 和 DuplicateColumn3。

DELETE
FROM MyTable
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM MyTable
GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)

引用自:http://blog.sqlauthority.com/2007/03/01/sql-server-delete-duplicate-records-rows/

【讨论】:

  • 这只会删除 1 条记录。
【解决方案2】:

查找所有重复行的一种方法是将表连接到所有可能具有重复数据的列上,并过滤掉 col1 值相同的行,如下所示:

select distinct a.col1
from t1 a inner join t1 b on a.col2 = b.col2 and a.col3 = b.col3
where a.col1 <> b.col1

您将使用它从 t1 插入 t2(根据我对您的问题的评论,假设您想在 t2 中保留来自 t1 的 col1 值):

insert into t2 (col1, col2, col3)
select col1, col2, col3
from t1
where col1 in (
    select distinct a.col1
    from t1 a inner join t1 b on a.col2 = b.col2 and a.col3 = b.col3
    where a.col1 <> b.col1
)

然后从 t1 中删除:

delete t1
where col1 in (
    select distinct a.col1
    from t1 a inner join t1 b on a.col2 = b.col2 and a.col3 = b.col3
    where a.col1 <> b.col1
)

这可以通过使用临时表来保存 col1 值来简化,这样您就不必第二次进行自连接。使用临时表也会更安全。由于两个单独的查询每个都执行自连接,因此可以(远程)从 t1 中删除行而不将它们插入到 t2 中(即,如果在您对 t2 进行插入和从 t1 删除之间将新的重复项写入 t1,则新插入到 t1 的行将在第二个自连接中匹配)。

此外,对于删除,您可以使用 t2 而不是再次在 t1 上执行自连接(同样,如果我的假设是正确的并且您在 t2 中保留 col1 值)。

【讨论】:

    【解决方案3】:
    INSERT INTO T2(Col2, Col3)
    SELECT Col2, Col3
    FROM T1
    WHERE EXISTS (  SELECT * 
                    FROM T1 AS T 
                    WHERE   T.Col2 = T1.Col2
                        AND T.Col3 = T1.Col3
                        AND T.Col1 <> T1.Col1
                )
    
    DELETE FROM T1 
    WHERE EXISTS (  SELECT * 
                    FROM T2 
                    WHERE   T2.Col2 = T1.Col2
                        AND T2.Col3 = T1.Col3
                )
    

    【讨论】:

      【解决方案4】:

      搞定了。

      将所有重复记录插入 t2。

      insert into t2
      select src.col2, src.col3 from t1 src
      inner join (select t1.col2, t1.col3 from t1
                  group by t1.col2, t1.col3
                  having count(*) > 1) duplicates 
      on src.col2 = duplicates.col2 and src.col3 = duplicates.col3
      

      从 t1 中删除重复项。

      delete from t1
      where t1.col1 in (
          select src.col1 from t1 src
              inner join (
                          select t1.col2, t1.col3 from t1
                          group by t1.col2, t1.col3
                          having count(*) > 1) duplicates
                          on src.col2 = duplicates.col2 and src.col3 = duplicates.col3
                         )
      )
      

      【讨论】:

        【解决方案5】:
        Select * into temp(temporary table) 
         from tablename 
               group by column_name1,column_name2 
                 having (count(*)>=1)
        

        --- 数据被插入到临时表中,没有任何重复

        drop tablename
        
        select * into Tablename from temp
        

        【讨论】:

          猜你喜欢
          • 2018-04-07
          • 1970-01-01
          • 1970-01-01
          • 2017-09-29
          • 2010-10-07
          • 2012-12-07
          • 2020-04-22
          相关资源
          最近更新 更多