64

我有一张桌子,里面有id,yearcount

我想获取MAX(count)每个id并在它发生时保留year它,所以我进行了以下查询:

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

不幸的是,它给了我一个错误:

错误:列“table.year”必须出现在 GROUP BY 子句中或在聚合函数中使用

所以我尝试:

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

但是,它不这样做MAX(count),它只是按原样显示表格。我想是因为当按yearand分组时id,它会获得该id特定年份的最大值。

那么,我该如何编写该查询?我想知道发生这种情况idMAX(count)年份和年份。

4

2 回答 2

90

最短(也可能是最快)的查询是 with ,它是 SQL 标准子句DISTINCT ON的 PostgreSQL 扩展:DISTINCT

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;

结果由idetc. 订购,这可能会或可能不会受到欢迎。在任何情况下,它都比“未定义”要好。

它还以明确定义的方式打破联系(当多个年份共享相同的最大计数时):选择最早的年份。如果你不介意,yearORDER BY. 或者用 选择最近的一年year DESC

对于per的许多id行,其他查询技术(快得多)。看:

于 2012-11-11T02:08:43.147 回答
59
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
于 2012-11-10T20:15:16.103 回答