【问题标题】:PostgreSQL: top n entries per item in same tablePostgreSQL:同一个表中每个项目的前 n 个条目
【发布时间】:2011-11-28 15:38:31
【问题描述】:
| uId |   title   |  amount  |  makers  |  widgets  |
   1     richard      998       xcorp     sprocket
   2     swiss        995       ycorp     framitz
   3     ricky         90       zcorp     flobber
   4     ricky2       798       xcorp     framitz
   1     lilrick      390       xcorp     sprocket
   1     brie         200       mcorp     gullywok
   1     richard      190       rcorp     flumitz
   1     brie         490       bcorp     sprocket

等等……

我试图只检索每个 makers 的 3 条记录,前 3 条 amounts 和它们产生的 widgets

这是我所拥有的:

SELECT amount, makers FROM (SELECT amount, makers, (SELECT count(*) FROM  entry  as t2
WHERE t2.amount = t1.amount and t2.makers >= t1.makers) AS RowNum
FROM entry as t1
) t3
WHERE t3.RowNum<4 order by amount;

这是返回我真正需要的吗?有没有更好的方法来解决这个问题?我见过的大多数做这种事情的方法是在不同的表上进行连接等,我需要的所有信息都在一个表上。

预期输出:

| uId |   title   |  amounts  |  makers  |  widgets  |
  1      richard      998        xcorp     sprocket
  41     swiss        995        xcorp     widget
  989    richard      989        xcorp     sprocket
  22     swiss        995        ycorp     framitz
  92     swiss        990        ycorp     widget
  456    swiss        895        ycorp     flobber
  344    ricky        490        zcorp     flobber
  32     tricky       480        zcorp     flobber
  13     ricky        470        zcorp     flobber

等等……

makers 的顺序与为每个makers 获得前 3 个amounts 和他们提供的widgets 无关紧要。 makers的个数设置好了,一直有xmakers

【问题讨论】:

  • 鉴于您问题中的示例数据,您能否将预期输出显示为表格?
  • 鉴于您的示例数据,预期的输出似乎没有任何意义。此外,如果您需要帮助,您可能应该返回并接受过去对您的问题的回答。向那些帮助过您的人表示感谢既是礼貌的做法,也是在其他人试图找到您已经提出的问题的答案时使本网站更加有用。
  • 做到了!我的疏忽和感谢!
  • 来自 100 万条记录:我需要 3 个“数量”最高的“标题”和他们制作的“小部件”,按“制造商”分组

标签: sql postgresql greatest-n-per-group


【解决方案1】:
SELECT *
FROM (
   SELECT uid,
          title, 
          amount, 
          maker, 
          widgets,
          rank() over (partition by maker order by amount desc) as rank
   FROM entry  
) t
WHERE rank <= 3

【讨论】:

  • rank() 可能有间隙和重复,因此过滤器rank &lt;= 3 每组可能返回多于或少于 3 行。 row_number() 可能更合适。
  • 你是对的。另一种解决方案是dense_rank(),它不会产生间隙。
  • 我要查找这些并测试结果,我会回来谢谢!
  • 很好的解决方案,而且很简单!非常感谢!我以前从未使用过分区或排名!
  • @wannabe:然后使用row_number()
猜你喜欢
  • 2016-11-25
  • 2021-12-09
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 2022-11-15
  • 2021-11-06
相关资源
最近更新 更多