2014-12-11 66 views
1

以下的前三名是我的示例表和行PostgreSQL的:選擇各組

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 
+0

一個解決方案是在這裏:http://sqlfiddle.com/#!15/5692e/5。但該列是文本類型,因此不建議使用分區。我在想別的東西。 – 2014-12-11 05:18:15

+0

同樣的問題與答案在這裏:http://stackoverflow.com/questions/1124603/grouped-limit-in-postgresql-show-the-first-n-rows-for-each-group – 2014-12-11 11:37:55

回答

8

試試這個:

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...

+2

你應該使用'order by val DESC' – 2014-12-11 05:24:33

+0

感謝您的建議,我改變了它。 – Veera 2014-12-11 05:25:33

+0

好吧,我腦子裏有同樣的東西,我把它作爲評論發佈。但是東西是文本類型的列,所以如果數據字符串非常大並且有很多這樣的字符,那麼它會造成性能問題。 – 2014-12-11 05:31:04

3

由於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但是,當然,你應該明確你的數據和使用情況測試性能。