【问题标题】:Postgres group by columns and within group select other columns by max aggregatePostgres 按列分组并在组内按最大聚合选择其他列
【发布时间】:2016-07-11 18:40:15
【问题描述】:

这可能是一个标准问题,我已经关闭了其他一些 的答案,但到目前为止无法解决我当前的问题。

A              B             C
+----+-------+ +----+------+ +----+------+-------+
| id | start | | id | a_id | | id | b_id | name  |
+----+-------+ +----+------+ +----+------+-------+
|  1 |     1 | |  1 |    1 | |  1 |    1 | aname |
|  2 |     2 | |  2 |    1 | |  2 |    2 | aname |
+----+-------+ |  3 |    2 | |  3 |    3 | aname |
               +----+------+ |  4 |    3 | bname |
                             +----+------+-------+

用英文我想完成的是:

  1. 对于每个 c.name,根据 a.start 中的开始时间选择其最新条目

我试过的SQL如下:

SELECT a.id, a.start, c.id, c.name 
FROM a
INNER JOIN (
    SELECT id, MAX(start) as start
    FROM a
    GROUP BY id
) a2 ON a.id = a2.id AND a.start = a2.start
JOIN b
ON a.id = b.a_id
JOIN c
on b.id = c.b_id
GROUP BY c.name;

失败并出现以下错误:

ERROR: column "a.id" must appear in the GROUP BY clause or be used in an aggregate function Position: 8

为了有用,我确实需要查询中的 id,但不能对它们进行分组,因为它们是唯一的。这是我喜欢上面第一种情况的输出示例:

+------+---------+------+--------+
| a.id | a.start | c.id | c.name |
+------+---------+------+--------+
|    2 |       2 |    3 | aname  |
|    2 |       2 |    4 | bname  |
+------+---------+------+--------+

这是Sqlfiddle

编辑 - 删除第二种情况

【问题讨论】:

  • GROUP BY c.name; 不是必需的。
  • 我建议您从这个问题中删除第二个请求(在有人回答之前),使用distinct on 接受答案,然后针对第二部分提出另一个问题。 Stack Overflow 不提供额外积分。

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


【解决方案1】:

案例一

select distinct on (c.name)
    a.id, a.start, c.id, c.name
from
    a
    inner join
    b on a.id = b.a_id
    inner join
    c on b.id = c.b_id
order by c.name, a.start desc
;
 id | start | id | name  
----+-------+----+-------
  2 |     2 |  3 | aname
  2 |     2 |  4 | bname

案例 2

select distinct on (c.name)
    a.id, a.start, c.id, c.name
from
    a
    inner join
    b on a.id = b.a_id
    inner join
    c on b.id = c.b_id
where
    b.a_id in (
        select a_id
        from b
        group by a_id
        having count(*) > 1
    )
order by c.name, a.start desc
;
 id | start | id | name  
----+-------+----+-------
  1 |     1 |  1 | aname

【讨论】:

  • 感谢您这么快的答复!如果我需要将 distinct 扩展到 c 中的其他列,我假设我只是将它附加到 distinct 语句,但也在 order by 内?另外,我猜随着连接的总行数由于多种排序而增加,它的性能会很快变差?
  • @DavidE 除了强制性的c.name 和非层级的a.start 之外,您还可以在order by 子句中添加项目。选择列表是免费的。检查explain analyze
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 2020-10-27
  • 2015-08-03
相关资源
最近更新 更多