简体   繁体   English

Oracle 8i中的行数查询

[英]rowcount query in Oracle 8i

I have a table Department_history and here is the count of records for each department. 我有一个表Department_history,这是每个部门的记录数。

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. 我只想在表中保留每个部门的10条记录。

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). 我该如何运行一个查询,以删除每个部门名称的数据(如果它是> 10条记录)。 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: 您更新的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 . 它与您已经尝试过的类似,但是not in子句应该检查所有3个标识列,而不是department_name, id, report_runtime ,这report_runtimereport_runtime department_name, id, report_runtime report_runtime Otherwise, you might accidentally delete the wrong rows. 否则,您可能会意外删除错误的行。

I also used row_number instead of rank . 我也用row_number代替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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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