2012-11-10 104 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中的聚合函数。