简体   繁体   中英

rowcount query in Oracle 8i

I have a table Department_history and here is the count of records for each department.

select department_name, Id, count(1) total_rows_COUNT from Department_history
where 
group by Department_history,id
order by 2 desc

result:

department_name         ID     total_rows_COUNT 
Accounting            4564     556
Finance               3434     671
Marketing             4353  234
IT                  1233    454

I want to keep only the 10 records for each department in the table.

if run this below query for each department like this, it works.

delete from Department_history a1 
where 
and a1.report_runtime NOT IN
(
   select report_runtime
   from (
       select a.*, rank() over ( partition by department_name, id  order by report_runtime desc) r
       from Department_history a
    ) rs
     where r <= 10 and department_name = 'Accounting'

)
and department_name = 'Accounting'

But I don't want to individually run this deletion for each department. how can I run one query that deletes the data for each department_name (if it is >10 records). I tries this. but it doesn't work.

delete from Department_history a1 
where 
and a1.report_runtime NOT IN
(
   select report_runtime
   from (
       select a.*, rank() over ( partition by department_name, id  order by report_runtime desc) r
       from Department_history a
    ) rs
     where r <= 10 

)

Can someone please advise?

test sample:

create table tst as select owner, view_name from all_views;

delete from tst
  where owner||'::'||view_name in
(  
select owner||'::'||view_name from (
select owner, view_name, rank() over (partition by owner order by view_name) r from tst
) where r > 10
)

your updated sql:

delete from Department_history
where id NOT IN
(
   select id
   from (
       select id, rank() over ( partition by department_name  
order by report_runtime desc) rnk
from Department_history
    ) s
     where s.rnk <= 10    
)

Try this. It's similar to what you already tried, but the not in clause should be checking against all 3 identifying columns, department_name, id, report_runtime , not just report_runtime . Otherwise, you might accidentally delete the wrong rows.

I also used row_number instead of rank . I think it's the better choice for your requirement. Though based on your description of the data, I don't think it actually makes a difference in this case.

delete from department_history
 where (department_name, id, report_runtime)
   not in (select department_name, id, report_runtime
             from (select department_name, id, report_runtime,
                          row_number() over (partition by department_name, id order by report_runtime desc) as rn
                     from department_history)
            where rn <= 10)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM