1

Please help me to know delete records based on the rownum where even id is duplicate it won't happen but if it is the case.

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

Query Tried but deletes all 6 rows.

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

But this Query gives correct result:

SELECT MIN(rownum)
FROM a
GROUP BY name

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

Expected Result :

    ROWNUM         ID NAME
---------- ---------- ----------
         4          1 leo_1
         5          2 leo_2
         6          3 leo_3
sunleo
  • 10,589
  • 35
  • 116
  • 196

3 Answers3

7

Use the 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 )

Of course, you could do a.rowid < b.rowid as well. The rowid is just the physical address of the row so it doesn't matter whether you delete the row that has the larger or the smaller address.

Your expected results, though, don't make sense.

Expected Result :

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

The rownum of a result set is always assigned at query time. That means that a particular row may appear with different rownum values in different queries (or when the same query is run multiple times). rownum is always sequential so you can never have a rownum of 4 in a result set without also having rownum values of 1, 2, and 3 in the same result set. Whichever duplicate row you delete, your result will be

Expected Result :

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

But the rownum values are arbitrary. It would be just as valid for Oracle to return

Expected Result :

    ROWNUM         ID NAME
---------- ---------- ----------
         1          2 leo_2
         2          3 leo_3
         3          1 leo_1
Justin Cave
  • 227,342
  • 24
  • 367
  • 384
2
DELETE FROM a
WHERE rowid not in
(SELECT MIN(rowid) FROM a group BY name);
Sai
  • 659
  • 4
  • 12
  • 21
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 is the primary key column and c2 is the column with duplicate value.

sabya
  • 109
  • 2
  • 4
  • 20