Hi, with Oracle, how to delete all rows that belong to the following result?

SELECT * FROM (SELECT DATA FROM MY_TABLE WHERE KEY = X ORDER BY STAMP DESC) WHERE ROWNUM > 10

Don't know, how to pack this resultset description in the WHERE CLAUSE of the DELETE command. Thanks for any advice.

Kind regards, dx05

asked Jan 23 '13 at 15:55

dx05's gravatar image

dx05
16113


One Answer:

Hi!

First of all, I think you SQL will never return anything:

create table my_table (data char(200), key numeric, stamp date);
insert into my_table select 'junk', trunc(rownum/100), sysdate - interval '1' hour * rownum 
  from dual connect by rownum <= 10000;

Now your statement:

SELECT * FROM (SELECT DATA 
                 FROM MY_TABLE WHERE KEY = 17
                ORDER BY STAMP DESC) WHERE ROWNUM > 10
no rows selected

Without where filter on rownum:

100 rows selected.

So, you'd probably expect your query to return 90 rows, but it doesn't because rownum doesn't work that way. To make it work, you must materialize it in the inner query:

SELECT * FROM (SELECT DATA, rownum RN 
                 FROM MY_TABLE WHERE KEY = 17
                ORDER BY STAMP DESC) WHERE RN > 10

 90 rows selected.

This is also explained in my (free online) book.

The next step is to put this into a delete statement. Let's us an IN clause for that:

delete from my_table where rowid in (
SELECT rid FROM (SELECT DATA, rownum RN, rowid rid
                   FROM MY_TABLE WHERE KEY = 17
                  ORDER BY STAMP DESC) WHERE RN > 10
)

I've used the pseudocolumn rowid here because I didn't define a primary key. The trick is basically to select anything that unambigously defines the rows which are to be deleted (rowid, or better, the primary key) and use this with an IN to delete them.

answered Feb 06 '13 at 12:11

Markus%20Winand's gravatar image

Markus Winand ♦♦
93651120

Thx a lot, you helped me to increase my understanding :-) - dx05

(Feb 08 '13 at 12:34) dx05