这是一个选择一组所需行的查询:
select max(a), b, c, d, e
from T
group by b, c, d, e;
该表在id
列中有一个主键。
我想通过从每个行中获取主键来在另一个查询中标识这些行。我该怎么办?这不起作用:
select id, max(a), b, c, d, e
from T
group by b, c, d, e;
ERROR: column "T.id" must appear in the GROUP BY clause or be used in an aggregate function
我在其他一些postgresql问题中试过这个问题,但没有运气:
select distinct on (id) id, max(a), b, c, d, e
from T
group by b, c, d, e;
ERROR: column "T.id" must appear in the GROUP BY clause or be used in an aggregate function
我该怎么办?我知道每个结果只能有一个id
,因为它是主键...我真的希望主键和其余数据一起,对于初始(工作)查询返回的每一行。
答案 0 :(得分:5)
如果你不关心你得到哪个id
那么你只需要将id
包装在一些保证给你有效id
的聚合函数中。我想到了max
和min
聚合:
-- Or min(id) if you want better spiritual balance.
select max(id), max(a), b, c, d, e
from T
group by b, c, d, e;
根据您的数据,我认为使用窗口功能将是一个更好的计划(感谢邪恶的otto引导到头部):
select id, a, b, c, d, e
from (
select id, a, b, c, d, e, rank() over (partition by b,c,d,e order by a desc) as r
from T
) as dt
where r = 1
答案 1 :(得分:3)
由于您分组这一事实,每个返回的记录可以(并且很可能)有多个匹配的记录(例如,多个id
值)。
PostgreSQL非常严格 - 它不会猜到你的意思。
b,c,d,e
array_agg
分组功能获取每条记录id
值的数组。请参阅此问题:Postgresql GROUP_CONCAT equivalent?
我建议你认为#3是最有效的可能性。
希望这会有所帮助。谢谢!
答案 2 :(得分:1)
将原始查询用作子查询,并使用这些结果连接回原始表以查找ID。
SELECT T.id, T.a, T.b, T.c, T.d, T.e
FROM (SELECT max(a) AS MaxA, b, c, d, e
FROM T
GROUP BY b,c,d,e) q
INNER JOIN T
ON T.a = q.MaxA
AND T.b = q.b
AND T.c = q.c
AND T.d = q.d
AND T.e = q.e
答案 3 :(得分:1)
这不是你提出的问题,但我怀疑你要做的是让单行对应于由其他几列定义的每个组的一列的最大值。例如,找一整天的最热的星期一/星期二/等。
我发现这样做的最佳方法是使用视图查找组的所有最大值。如果您的原始表是
create table T as (
id integer primary key,
a integer,
b integer,
c integer,
d integer)
然后将“max”视图创建为
create view T_maxgroups as
select max(a) as a, b, c, d
from T
group by b, c, d
(这是您的初始查询)然后将该视图加入到您的表中以获取具有最大值的行:
select T.* from T join maxgroups using (a,b,c,d)
答案 4 :(得分:0)
select T.id, max(a), b, c, d, e
from T
group by T.id b, c, d, e;