【问题标题】:Select top three values in each group选择每组中的前三个值
【发布时间】:2015-02-09 12:21:48
【问题描述】:

以下是我的示例表和行

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);

我想获得每家公司的前 3 名价值,预期输出是:

company  val
---------------
com1     5
com1     4
com1     3
com2     55
com2     44
com2     33
com3     555
com3     444
com3     333

【问题讨论】:

标签: postgresql greatest-n-per-group


【解决方案1】:

试试这个:

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

--Quick Demo Here...

【讨论】:

  • 你应该使用order by val DESC
  • 谢谢建议,我改了。
  • 好吧,我也有同样的想法,我将其发布为 cmets。但问题是列是文本类型,所以如果数据字符串很大并且有很多这样的,那么它会产生性能问题。
  • 它解决了我上面回答的问题,因为 SQL SELECT 将返回重复的行。我的逻辑我想返回所有行但任何行重复值我的业务逻辑需要限制前 2 个返回(不是全部),谢谢
【解决方案2】:

从 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;

might be faster 但是,当然,您应该专门针对您的数据和用例测试性能。

【讨论】:

    【解决方案3】:

    您可以尝试从 Postgres v9.0 开始提供的数组。

    WITH com_ordered AS (SELECT * FROM com ORDER BY company,val DESC)
    SELECT company,unnest((array_agg(val))[0:3])
      FROM com_ordered GROUP BY company;
        
    

    【讨论】:

      猜你喜欢
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多