按列和组内的Postgres组按max aggregate选择其他列

时间:2016-07-11 18:40:15

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

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

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中的开始时间选择其最新条目
  2. 我尝试过的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

    编辑 - 删除了第二个案例

1 个答案:

答案 0 :(得分:2)

Case 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

Case 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