PostgreSQL MAX 和 GROUP BY
Posted
技术标签:
【中文标题】PostgreSQL MAX 和 GROUP BY【英文标题】:PostgreSQL MAX and GROUP BY 【发布时间】:2012-10-30 19:21:21 【问题描述】:我有一张桌子,上面有 id
、year
和 count
。
我想为每个id
获取MAX(count)
并在它发生时保留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)
,它只是按原样显示表格。我想是因为当按year
和id
分组时,它会获得该特定年份的id
的最大值。
那么,我该如何编写该查询?我想得到id
´s MAX(count)
以及发生这种情况的年份。
【问题讨论】:
如果 id,year 是唯一的,max(thing)
与 thing
相同。另请注意,“计数”是一个关键字,(在某些方言中,年份也是如此,IIRC)
您希望每个 id 获得哪一年?没有“年”,有不止一个,也许你想要MAX(year)
?
是的,它们是独一无二的,所以我明白了。我想获得 ids MAX(thing) 并且还想看看发生在哪一年。 (我的代码中没有写计数,只是一个例子)
我想得到那个 ID 最大化“事物”列的年份
【参考方案1】:
最短(也可能是最快)查询将使用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
许多 行,其他查询技术(快得多)。见:
【讨论】:
查询执行时间更短的完美解决方案。我尝试分组并获取最大数据。但它很慢。谢谢你欧文.. 我还有另一个同样的问题,我的 MAX() 有两个输出,所以输出只是第一个出现的输出,我想同时得到它们,我该怎么做?跨度> 也很好地阅读了可能更好的替代方案和讨论wiki.postgresql.org/wiki/Loose_indexscan【参考方案2】: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
【讨论】:
@user1504577:当多个年份共享最大计数时,所有这些查询都会为每个 id 返回多个值。在这种常见情况下,您必须定义您想要的内容。显示所有?选一个?最新的/最早的/什么?在一列中显示年份列表? @a_horse_with_no_name 你能解释一下这些查询的优缺点吗? 选择这个答案,因为它提供了适用于不同 SQL 引擎的查询,在服务器之间迁移已经像 f**k 一样烦人。以上是关于PostgreSQL MAX 和 GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章
postgreSQL使用sql归一化数据表的某列,以及出现“字段 ‘xxx’ 必须出现在 GROUP BY 子句中或者在聚合函数中”错误的可能原因之一