使用sql中的rownum删除重复记录

时间:2014-01-11 19:47:59

标签: sql oracle

请帮助我知道基于rownum的删除记录,即使id是重复的,也不会发生,但如果是这样的话。

select rownum,a.* from a;

    ROWNUM         ID NAME
---------- ---------- ----------
         1          1 leo_1
         2          2 leo_2
         3          3 leo_3
         4          1 leo_1
         5          2 leo_2
         6          3 leo_3

查询已尝试但删除了所有6行。

DELETE FROM a
WHERE rownum not in
(SELECT MIN(rownum)
FROM a
GROUP BY name);

但是这个Query给出了正确的结果:

SELECT MIN(rownum)
FROM a
GROUP BY name

    ROWNUM
----------
         1
         2
         3

预期结果:

    ROWNUM         ID NAME
---------- ---------- ----------
         4          1 leo_1
         5          2 leo_2
         6          3 leo_3

3 个答案:

答案 0 :(得分:7)

使用rowid

DELETE FROM table_name a
 WHERE EXISTS( SELECT 1
                 FROM table_name b
                WHERE a.id = b.id
                  AND a.name = b.name
                  AND a.rowid > b.rowid )

当然,您也可以a.rowid < b.rowidrowid只是行的物理地址,因此删除具有较大或较小地址的行无关紧要。

但是,您的预期结果没有意义。

Expected Result :

        ROWNUM         ID NAME
    ---------- ---------- ----------
             4          1 leo_1
             5          2 leo_2
             6          3 leo_3

结果集的rownum始终在查询时分配。这意味着特定行可能在不同的查询中显示不同的rownum值(或者当多次运行相同的查询时)。 rownum始终是连续的,因此在结果集中永远不会有rownum,而在同一结果集中也不会有rownum值1,2和3。无论您删除哪个重复行,结果都是

预期结果:

    ROWNUM         ID NAME
---------- ---------- ----------
         1          1 leo_1
         2          2 leo_2
         3          3 leo_3

rownum值是任意的。返回

对Oracle来说同样有效

预期结果:

    ROWNUM         ID NAME
---------- ---------- ----------
         1          2 leo_2
         2          3 leo_3
         3          1 leo_1

答案 1 :(得分:2)

DELETE FROM a
WHERE rowid not in
(SELECT MIN(rowid) FROM a group BY name);

答案 2 :(得分:2)

delete from tb_test where c1 in (select c1 from (select c1,c2, 
row_number() over (partition by c2 order by c2)  rn
from tb_test) a where a.rn >1 );

C1是主键列,c2是具有重复值的列。