2012-11-10 103 views
18

我有idyearcount表。PostgreSQL的MAX和GROUP BY

我想要得到的MAX(count)每個id並保持year當它發生,所以我提出這個查詢:

SELECT id, year, MAX(count) 
FROM table 
GROUP BY id; 

不幸的是,它給了我一個錯誤:

ERROR: column "table.year" must appear in the GROUP BY clause or be used in an aggregate function

所以我嘗試:

SELECT id, year, MAX(count) 
FROM table 
GROUP BY id, year; 

但是然後,它d沒有做MAX(count),它只是顯示錶格。我想,因爲當由yearid分組時,它獲得該特定年份的id的最大值。

那麼,我該如何編寫該查詢?我想獲得idMAX(count)以及發生這種情況的年份。

+1

如果{id,year}是唯一的,'max(thing)'與'thing'相同。另外請注意,「count」是一個關鍵詞,(以及一些方言中的年份,IIRC) – wildplasser

+0

您想要每個ID使用哪一年?沒有「今年」,有更多的,也許你想'MAX(年)'? – mata

+0

是的,他們是獨一無二的,所以我得到了東西。我想獲得ids MAX(東西),並且看看發生在哪一年。 (我沒有寫在我的代碼計數,只是一個例子) –

回答

21
select * 
from (
    select id, 
     year, 
     thing, 
     max(thing) over (partition by id) as max_thing 
    from the_table 
) t 
where thing = max_thing 

或:

select t1.id, 
     t1.year, 
     t1.thing 
from the_table t1 
where t1.thing = (select max(t2.thing) 
        from the_table t2 
        where t2.id = t1.id); 

select t1.id, 
     t1.year, 
     t1.thing 
from the_table t1 
    join ( 
    select id, max(t2.thing) as max_thing 
    from the_table t2 
    group by id 
) t on t.id = t1.id and t.max_thing = t1.thing 

或(同前與不同的符號)

with max_stuff as (
    select id, max(t2.thing) as max_thing 
    from the_table t2 
    group by id 
) 
select t1.id, 
     t1.year, 
     t1.thing 
from the_table t1 
    join max_stuff t2 
    on t1.id = t2.id 
    and t1.thing = t2.max_thing 
+0

@ user1504577:所有這些查詢返回多個值每個ID多年來共享最大計數。你將不得不在這種常見情況下定義你想要的。顯示所有?選一個?最新/最早的/無論什麼?在一列中顯示年份列表? –

+0

@a_horse_with_no_name你能解釋每個查詢的優缺點嗎? – Stratus3D

36

最短(以及可能的最快)的查詢將與DISTINCT ON ,SQL標準DISTINCT條款的PostgreSQL的擴展:

SELECT DISTINCT ON (1) 
     id, count, year 
FROM tbl 
ORDER BY 1, 2 DESC, 3; 

的數字是在SELECT列表序號位置,你可以講出來,太:

SELECT DISTINCT ON (id) 
     id, count, year 
FROM tbl 
ORDER BY id, count DESC, year; 

結果由id有序,這可能會也可能不會受到歡迎。無論如何,它比「未定義」要好。

它還以明確的方式打破關係(多年共享相同的最大數量):選擇最早的一年。如果您不在意,請從ORDER BY中刪除year。或者用year DESC挑選最近一年。

更多的解釋,鏈接,標杆在此密切相關的答案可能更快的解決方案:

旁白:在現實生活中查詢,您將無法使用一些的列名稱。 id是列名稱的非描述性反模式,countreserved word in standard SQLcount() Postgres中的聚合函數。