【问题标题】:Use GROUP_BY with extra columns in postgreSQL在 postgreSQL 中使用带有额外列的 GROUP_BY
【发布时间】:2021-02-02 03:31:52
【问题描述】:

假设我们有一个简单的表users

id  | name | company |  other columns.......
----+------+---------+-------------------------
 1  | A    | A1
 2  | A    | A2
 3  | B    | B1
 4  | C    | C1
 5  | C    | C2
 6  | C    | C3
 ....

我想按名称分组,并为idcompany 选择了最新值。我期望的结果是三列表:

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

有人有更好的主意吗?

【问题讨论】:

    标签: sql postgresql greatest-n-per-group


    【解决方案1】:

    使用distinct on:

    select distinct on (name) u.*
    from users u
    order by name, id desc;
    

    distinct on 是一个非常方便的 Postgres 扩展。它返回一组行的第一行。 “分组”基于distinct on 之后的列。排序基于order by 子句。

    还有另外两种常见的方法来解决这个问题。一种方法使用窗口函数:

    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;
    

    【讨论】:

    • 难以置信的答案!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 2021-07-03
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多