2011-09-30 49 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