您好,我在oracle中有一个表:
+ -----+----------+----------+-----------+ | ACC | TYPE | BILL_NUM | TYPE_COST | + -----+----------+----------+-----------+ | ACC1 | VOICE | 1 | 10 | | ACC1 | MMS | 1 | 5 | | ACC1 | VOICE | 2 | 20 | | ACC1 | MMS | 2 | 15 | | ACC1 | VOICE | 3 | 30 | | ACC2 | VOICE | 1 | 3 | | ACC2 | MMS | 1 | 4 | | ACC2 | MMS | 2 | 14 | | ACC2 | MMS | 3 | 24 | | ACC2 | MMS | 4 | 34 | + -----+----------+----------+-----------+
您可能会看到一个帐户有多个帐单,并且此帐户ACC1有3个帐单(最新为3个),而ACC2有4个帐单(最新为4个)。我想过滤出行,并且只需要查看每个帐户的最新2张账单。在这种情况下,我将使用帐户作为输入。我写了一个查询及其工作方式:
with
acclist as (
select * from (
select distinct acc,bill_num from testdata where acc='ACC1' order by bill_num desc )
where rownum<=2
)
select * from testdata td,acclist al where td.bill_num=al.bill_num and td.acc=al.acc
但是我相信这样做有更好的方法。有人可以为我提供更好的解决方案吗? 下面是参考表的创建:
create table TestData
(
ACC VARCHAR(9),
TYPE VARCHAR(20),
BILL_NUM NUMBER(9),
TYPE_COST NUMBER(9)
);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC1', 'VOICE', 1, 10);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC1', 'MMS', 1, 5);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC1', 'VOICE', 2, 20);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC1', 'MMS', 2, 15);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC1', 'VOICE', 3, 30);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC2', 'VOICE',1, 3);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC2', 'MMS', 1, 4);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC2', 'MMS', 2, 14);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC2', 'MMS', 3, 24);
insert into testdata (ACC, TYPE, BILL_NUM, TYPE_COST)
values ('ACC2', 'MMS', 4, 34);
commit;
答案 0 :(得分:0)
我想过滤出行,并且只需要查看每个帐户的最新2张账单
您可以使用row_number()
:
select *
from (
select t.*, row_number() over(partition by acc order by bill_num desc) rn
from mytable t
) t
where rn <= 2
ACC | TYPE | BILL_NUM | TYPE_COST :--- | :---- | -------: | --------: ACC1 | VOICE | 3 | 30 ACC1 | VOICE | 2 | 20 ACC2 | MMS | 4 | 34 ACC2 | MMS | 3 | 24
修改
如果您想允许联系(这意味着您可以在结果集中的每个帐户获得两个以上的记录),则可以改用dense_rank()
:
select *
from (
select t.*, dense_rank() over(partition by acc order by bill_num desc) rn
from mytable t
) t
where rn <= 2
Demo :
ACC | TYPE | BILL_NUM | TYPE_COST :--- | :---- | -------: | --------: ACC1 | VOICE | 3 | 30 ACC1 | VOICE | 2 | 20 ACC1 | MMS | 2 | 15 ACC2 | MMS | 4 | 34 ACC2 | MMS | 3 | 24