从Oracle表中删除所有重复记录,除了最早的记录。

7

我有两张表,一张是父表TableA,另一张是子表TableB。TableB中有一个或多个记录与TableA中的父记录相关联。我需要删除TableB中除最早日期之外的所有记录,也就是TableB中的所有重复记录。我认为不需要在语句中涉及TableA,但为了参考,我会将其包括在内。

TableA 
_______ 
SecID, SecName 
1,     Sec1
2,     Sec2
3,     Sec3
4,     Sec4

TableB
_________
IncID, SecID, PayDate 
16,    1,     11/03/2011
17,    1,     11/04/2011
18,    2,     10/01/2011
19,    3,     01/06/2011
20,    3,     01/09/2011
21,    3,     01/12/2011
22,    4,     10/06/2011

在上面的TableB中,我需要删除记录17、20和21,只留下每个SecID的一条记录。到目前为止,我的代码如下,但是出现了一个问题,它包括了我想要保留的最早的记录:
delete from TableB where PayDate not in (
  select min(PayDate)from TableB
  having ( count(PayDate) > 1 )
)
3个回答

22

你可以使用ROWID和分析函数:

SQL> DELETE FROM tableB
  2   WHERE ROWID NOT IN
  3           (SELECT first_value(ROWID)over(PARTITION BY secID ORDER BY paydate)
  4              FROM tableB);

3 rows deleted

SQL> select * from tableB;

     INCID      SECID PAYDATE
---------- ---------- -----------
        16          1 11/03/2011
        18          2 10/01/2011
        19          3 01/06/2011
        22          4 10/06/2011

你也可以使用一种更常规的半连接:

SQL> DELETE FROM tableB b_out
  2   WHERE EXISTS (SELECT NULL
  3                   FROM tableB b_in
  4                  WHERE b_in.secID = b_out.secID
  5                    AND b_in.paydate < b_out.paydate);

3 rows deleted

嗨,Vincent,感谢您的回复。我尝试了半连接,看起来应该可以工作,但它保留的是最新的记录而不是最旧的记录。 - Ciarán Bruen
@Ciaran:你说得对,我没有检查结果。我已经更新了我的答案,现在应该可以工作了。 - Vincent Malgrat
那就是它了,谢谢。你有没有想法为什么我的原始查询不起作用? - Ciarán Bruen
2
@Ciaran:你需要指定要删除哪个secID,可能是像这样的语句 DELETE FROM TableB WHERE (secID, PayDate) NOT IN (SELECT secID, MIN(PayDate) FROM TableB GROUP BY secID) - Vincent Malgrat
很好地发现了这一点,你上面的查询和上述查询都返回相同的结果。干杯! - Ciarán Bruen

7

表格

 ID    RefCode   Code_Desc
 122   B122      The Notebook
 122   B122      The Notebook
 122   B122      The Notebook
 123   B123      A Walk to Remember
 123   B123      A Walk to Remember
 123   B123      A Walk to Remember
 123   B123      A Walk to Remember

删除除一条记录之外的所有重复记录

delete from TABLE a where rowid<(select max(rowid) from TABLE b where a.ID = b.ID)

删除指定重复记录之外的所有重复记录

delete from TABLE a where rowid<(select max(rowid) from TABLE b where a.ID = b.ID and a.ID = 122)


0
delete from your_table a
where a.rowid not in 
(
  select max(b.rowid) from your_table b
  group by b.col1,b.col2....b.coln
)

这将获取所有唯一的行标识(rowid),并且除了这些行标识,SQL 将删除所有行。


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