Select 每个地区的前 3 条记录

Select top 3 records from each territory

我正在努力使用 PostgreSQL 查询 select 每个类别的前 3 条记录。我有 3 tables(如下所示)和数据,

地理:

公式:

formulary_controller:

我想 select 一个地区下每个地区的前 3 个处方集按生命 desc 排序。

到目前为止我提出的查询是,

select 
    t.name territory, f.name formulary, sum(f.lives) lives
from formulary f join geography t on f.territory_id = t.id
where t.parent_id = '1'
group by t.name, f.name
order by lives desc, territory;

如果我应用 limit 3 top 上面的查询将给我所有地区的前 3 名,但我想 select keystone 区域下每个地区的前 3 名处方集。

创建 table 和加载虚拟数据的查询:

create table formulary_controller
(
    id SERIAL primary key,
    name varchar(300)
);

create table geography
(
    id SERIAL primary key,
    name varchar(250),
    parent_id integer references geography(id)
);

create table formulary
(
    id SERIAL primary key,
    name varchar(300),
    lives integer,
    controller_id integer references formulary_controller(id),
    territory_id integer references geography(id)
);


insert into formulary_controller (id, name)
values(1, 'cont1'), (2, 'cont2');


insert into geography (id, name, parent_id)
values
(1, 'keystone', null),
(2, 'pittsburgh', 1),
(3, 'Baltimore', 1);


insert into formulary
(name, lives, controller_id, territory_id)
values
('PA FRM 1', 200, 1, 2),
('PA FRM 2', 1400, 1, 2),
('PA FRM 3', 1300, 1, 2),
('PA FRM 4', 100, 1, 2),
('PA FRM 5', 2430, 1, 2),
('BA FRM 1', 100, 2, 3),
('BA FRM 2', 2300, 2, 3),
('BA FRM 3', 1200, 2, 3),
('BA FRM 4', 1650, 2, 3),
('BA FRM 5', 1200, 2, 3);

您可以使用以下查询找到前 3 territory_id row_number()

with cte (select a.*, 
row_number() over(partition by territory_id order by lives desc) rn
from formulary a
) select cte.* from cte where rn<=3

您可以尝试以下 - DEMO HERE

select * from
(
select 
    t.name territory, f.name formulary, sum(f.lives) lives,
      row_number() over(partition by t.name order by sum(f.lives) desc) as rn
from formulary f join geography t on f.territory_id = t.id
where t.parent_id = '1'
group by t.name,f.name
)A where rn<=3