Oracle SQL根据列删除重复记录

时间:2014-12-22 07:03:14

标签: sql oracle

我有一张记录表:

DATE           NAME    AGE    ADDRESS
01/13/2014     abc     27     us
01/29/2014     abc     27     ma            <- duplicate
02/03/2014     abc     27     ny            <- duplicate
02/03/2014     def     28     ca

我想删除记录编号2和3,因为它们是基于名称和年龄的记录1的重复记录。 DATE列是一个时间戳,基于添加时的记录(sql日期)并被认为是唯一的。

我发现这个sql但不确定它是否会起作用并且有点担心,因为该表有200万条记录并且删除错误的记录将是一个坏主意:

SELECT A.DATE, A.NAME, A.AGE
  FROM table A
 WHERE EXISTS (SELECT B.DATE
             FROM table B
            WHERE B.NAME = A.NAME
          AND B.AGE = A.AGE);

这个记录有很多实例,所以如果有人可以帮我写一个sql来删除这些记录吗?

3 个答案:

答案 0 :(得分:0)

<强>查询

DELETE FROM tbl t1
WHERE dt IN 
(
  SELECT t1.dt
  FROM   tbl t1
  JOIN   tbl t2 ON 
  (
    t2.name = t1.name
    AND t2.age=t1.age
    AND t2.dt > t1.dt
  )
);

<强> Fiddle demo

答案 1 :(得分:0)

delete from table 
 where (date, name, age) not in ( select max( date ), name, age from table group by name, age )

删除之前使用

进行验证
select * from table 
 where (date, name, age) not in ( select max( date ), name, age from table group by name, age ) 

答案 2 :(得分:0)

ROW_NUMBER分析函数会有所帮助(由Oracle和Sqlserver支持) 为分区内的每一行分配唯一的有序编号的逻辑需要在ORDER BY子句中小心实现。

SELECT A_TABLE.*,
        ROW_NUMBER ()
        OVER (PARTITION BY NAME, AGE
              ORDER     BY DATE  DESC)
           seq_no
FROM A_TABLE;

然后您可以将结果用于删除操作:

Delete A_TABLE 
where DATE,NAME,AGE IN 
(
   SELECT DATE,NAME,AGE FROM
   (
      SELECT A_TABLE.*,
            ROW_NUMBER ()
            OVER (PARTITION BY NAME, AGE
              ORDER     BY DATE DESC)
               seq_no
      FROM A_TABLE;
   ) 
   WHERE seq_no != 1
 )