下面的表使用id
和ts
的组合主键来实现历史性:
create table "author" (
"id" bigint not null,
"ts" timestamp not null default now(),
"login" text unique not null,
primary key ("id", "ts")
);
现在我只对最新的login
值感兴趣。为此,我按id
分组
select "id", max("ts"), "login" from "author" group by "id";
但是这会引发一个错误:应该在聚合函数中使用login
。
id
和max("ts")
唯一地标识一行,因为tupple (id,ts)是主键。我需要login
,它与id
和max("ts")
标识的行匹配。
我可以编写一个子选择来查找login
。
select ao."id", max(ao."ts"),
(select ai.login from "author" ai
where ao."id" = ai."id" and max(ao."ts") = ai.ts)
from "author" ao
group by "id";
这是工作的,但它是相当嘈杂和不太聪明,因为它搜索整个表,虽然搜索组将是足够的。
是否存在聚合函数,它避免了子选择,并给出了属于id
和max("ts")
的剩余的max("ts")
。
发布于 2018-11-06 16:25:47
您必须标识正确的键才能从表中获得您喜欢的值。
正确的关键是:
select "id", max("ts") from "author" group by "id";
并使用它获取您想要的登录:
select a1."id", a1.ts, a1.login
from "author" a1
inner join (select "id", max("ts") maxts, "login" from "author" group by "id") a2
ON a1.id = a2.id AND a1.ts = a2.maxts;
另一种方法是使用窗口函数:
SELECT "id", "ts", login
FROM (
select "id", "ts", CASE WHEN "ts" = max("ts") OVER (PARTITION BY "id") THEN 1 ELSE 0 END as isMax, "login" from "author" group by "id"
) dt
WHERE isMax = 1
还有其他几种方法可以剥去这只猫的皮,但这基本上就是要点。
https://stackoverflow.com/questions/53175831
复制相似问题