在 postgreSQL 中使用 GROUP_BY 和额外的列
Use GROUP_BY with extra columns in postgreSQL
假设我们有一个简单的 table users
:
id | name | company | other columns.......
----+------+---------+-------------------------
1 | A | A1
2 | A | A2
3 | B | B1
4 | C | C1
5 | C | C2
6 | C | C3
....
我想按名称分组,id
和company
选择了最新的值。我期望的结果是三列 table:
id | name | company |
----+------+---------+
2 | A | A2
3 | B | B1
6 | C | C3
....
我正在尝试使用 GROUP_BY
,但不知道如何包含 company
列:
SELECT
max(id),
name,
? # I don't know how to include company
FROM users
GROUP_BY name
有没有人有更好的主意?
使用distinct on
:
select distinct on (name) u.*
from users u
order by name, id desc;
distinct on
是一个非常方便的 Postgres 扩展。它 returns 一组行中的第一行。 “分组”基于 distinct on
之后的列。排序基于 order by
子句。
还有另外两种常见的方法可以解决这个问题。一种方法使用 window 函数:
select u.*
from (select u.*,
row_number() over (partition by name order by id desc) as seqnum
from users u
) u
where seqnum = 1;
或相关子查询:
select u.*
from users u
where u.id = (select max(u2.id) from users u2 where u2.name -= u.name);
甚至有一种“聪明”的方法可以使用 group by
来做到这一点。 Postgres 没有“第一个”或“最后一个”聚合函数。但是你可以使用数组:
select name, max(id),
(array_agg(company order by id desc))[1] as country
from users u
group by name;
假设我们有一个简单的 table users
:
id | name | company | other columns.......
----+------+---------+-------------------------
1 | A | A1
2 | A | A2
3 | B | B1
4 | C | C1
5 | C | C2
6 | C | C3
....
我想按名称分组,id
和company
选择了最新的值。我期望的结果是三列 table:
id | name | company |
----+------+---------+
2 | A | A2
3 | B | B1
6 | C | C3
....
我正在尝试使用 GROUP_BY
,但不知道如何包含 company
列:
SELECT
max(id),
name,
? # I don't know how to include company
FROM users
GROUP_BY name
有没有人有更好的主意?
使用distinct on
:
select distinct on (name) u.*
from users u
order by name, id desc;
distinct on
是一个非常方便的 Postgres 扩展。它 returns 一组行中的第一行。 “分组”基于 distinct on
之后的列。排序基于 order by
子句。
还有另外两种常见的方法可以解决这个问题。一种方法使用 window 函数:
select u.*
from (select u.*,
row_number() over (partition by name order by id desc) as seqnum
from users u
) u
where seqnum = 1;
或相关子查询:
select u.*
from users u
where u.id = (select max(u2.id) from users u2 where u2.name -= u.name);
甚至有一种“聪明”的方法可以使用 group by
来做到这一点。 Postgres 没有“第一个”或“最后一个”聚合函数。但是你可以使用数组:
select name, max(id),
(array_agg(company order by id desc))[1] as country
from users u
group by name;