PostgreSQL:同一个表中每个项目的前n个条目

rob*_*ger 5 sql postgresql greatest-n-per-group

| 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
Run Code Online (Sandbox Code Playgroud)

等等...

我试图每个只检索3条记录makers,前3条amountswidgets它们产生

这就是我所拥有的:

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;
Run Code Online (Sandbox Code Playgroud)

这会回归我真正需要的吗?有没有更好的方法来解决这个问题?我见过的大多数方法都是在不同的表上进行连接等,我需要的所有信息都放在一张桌子上.

预期产出:

| 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
Run Code Online (Sandbox Code Playgroud)

等等...

这个顺序makers并不重要,因为amounts每个人都获得了前三名makers,而widgets他们提供了前三名.设定的数量,makers总会有x makers

a_h*_*ame 15

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
Run Code Online (Sandbox Code Playgroud)

  • `rank()`可能有间隙和重复,因此过滤器`rank <= 3`可能每组返回多于或少于3行.`row_number()`可能更合适. (4认同)