PL/SQl,oracle 9i,使用sql删除重复行

Posted

技术标签:

【中文标题】PL/SQl,oracle 9i,使用sql删除重复行【英文标题】:PL/SQl, oracle 9i, deleting duplicate rows using sql 【发布时间】:2012-02-03 18:02:25 【问题描述】:

我们这里有一个场景,我们需要根据时间戳从表中删除所有重复的行。表结构如下所示:

项目 Ref1 Ref2 时间戳 1 A 测试1 2/3/2012 10:00:00 1 A 测试2 2/3/2012 11:00:00 1 A 测试1 2/3/2012 12:00:00 2 产品 1 2012 年 2 月 3 日 10:00:00 2 B 产品 2 2012 年 2 月 3 日 11:00:00 2 产品 2 2012 年 2 月 3 日 12:00:00

所以我们需要根据 item 和 ref1 从这个表中删除重复的行。像这里一样,我们应该只有 1 行的项目 1 和 ref1 A 具有最新的时间戳。与第 2 项相同,我们应该只有 1 行 ref1 A 具有最新的时间戳。

任何指针都会很棒

【问题讨论】:

【参考方案1】:

假设您想要的最终结果是包含这 3 行的表格

Item   Ref1   Ref2        Timestamp
1      A       test1      2/3/2012 12:00:00
2      B       prod2      2/3/2012 11:00:00
2      A       prod2      2/3/2012 12:00:00

类似

DELETE FROM table_name a
 WHERE EXISTS( SELECT 1
                 FROM table_name b
                WHERE a.item = b.item
                  AND a.ref1 = b.ref1
                  AND a.timestamp < b.timestamp );

应该假设没有两行具有相同的ItemRef1,它们都具有相同的Timestamp。如果可以有多行具有相同的ItemRef1,它们都具有最新的Timestamp,并且假设您不在乎保留哪一个

DELETE FROM table_name a
 WHERE EXISTS( SELECT 1
                 FROM table_name b
                WHERE a.item = b.item
                  AND a.ref1 = b.ref1
                  AND a.timestamp <= b.timestamp 
                  AND a.rowid     <  b.rowid);

【讨论】:

【参考方案2】:

您可以通过 Item 和 Ref1 查询您的记录分组,然后删除 Item 和 Ref 相等且时间戳

select Item
     , Ref1
     , max(Timestamp) tm
  from table
 group by Item, Ref1

有了结果……

delete from table where Item = ? and Ref1 = ? and Timestamp < ?

【讨论】:

【参考方案3】:

我手头没有安装 Oracle 9,所以我无法对此进行测试,但我相信这可能有效:

    创建一个视图,列出向您的记录添加“索引”:

    SELECT ROW_NUMBER( ) OVER (PARTITION BY Item, Ref1 ORDER BY Timestamp DESC) ix, * FROM table

    删除视图中ix大于1的记录

【讨论】:

以上是关于PL/SQl,oracle 9i,使用sql删除重复行的主要内容,如果未能解决你的问题,请参考以下文章

在 pl/SQL 中继续声明? [复制]

PL/SQL ORACLE:删除时触发更新

Oracle pl/sql:在事务中执行动态删除

在第二个逗号 Oracle / PL SQL 后删除字符串

在 oracle pl/sql 中如何选择嵌套类型?

去掉 PL/SQL 函数末尾的逗号 [Oracle PL/SQL]