PostgreSQL:选择每组中的前三名

zeo*_*ran 2 sql postgresql group-by greatest-n-per-group

以下是我的示例表和行

create table com (company text,val int);


insert into com values ('com1',1),('com1',2),('com1',3),('com1',4),('com1',5);

insert into com values ('com2',11),('com2',22),('com2',33),('com2',44),('com2',55);

insert into com values ('com3',111),('com3',222),('com3',333),('com3',444),('com3',555);
Run Code Online (Sandbox Code Playgroud)

我希望获得每家公司的前三大价值,预计产量为:

company  val
---------------
com1     5
com1     4
com1     3
com2     55
com2     44
com2     33
com3     555
com3     444
com3     333
Run Code Online (Sandbox Code Playgroud)

Vee*_*era 11

试试这个:

SELECT company, val FROM 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY 
             company order by val DESC) AS Row_ID FROM com
) AS A
WHERE Row_ID < 4 ORDER BY company
Run Code Online (Sandbox Code Playgroud)

- 在这里快速演示......

  • 你应该使用`order by val DESC` (2认同)

pos*_*est 6

从 v9.3 开始,您可以进行横向连接

select distinct com_outer.company, com_top.val from com com_outer
join lateral (
    select * from com com_inner
    where com_inner.company = com_outer.company
    order by com_inner.val desc
    limit 3
) com_top on true
order by com_outer.company;
Run Code Online (Sandbox Code Playgroud)

可能更快,但当然,您应该专门针对您的数据和用例测试性能。