2011-09-30 48 views
4
| 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 

等等PostgreSQL的:每个项目的前N个项目在同一个表

我想每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不要紧这么多的获得前3名amounts每个makers的顺序,以及他们所提供的widgets。的makers次数设定,总是会有xmakers

+0

鉴于你的问题的数据。例如,您可以显示预期outout为表? –

+0

根据您的示例数据,预期输出似乎没有任何意义。另外,如果你需要帮助,你应该回去接受你的问题的过去答案。当别人试图找到你已经问过的问题的答案时,承认那些帮助你的人并且使这个网站更有用。 –

+0

做到了!我的疏忽和感谢! – roberthuttinger

回答

13
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 
+3

'rank()'可能有差距和重复,因此过滤器排名< = 3'可能会返回每组多于或少于3行。 'row_number()'可能更合适。 –

+1

你说得对。另一种解决方案是'dense_rank()',它不会产生间隙。 –

+0

即时查看这些和测试结果,生病回到thx! – roberthuttinger