PostgreSQL按汇总分组

时间:2020-10-28 15:57:43

标签: sql postgresql

我需要group by id并选择最小/最大taskseqstart的{​​{1}}

end
 id | task | seq    
----+------+-----
  1 | aaa  |   1 
  1 | bbb  |   2
  1 | ccc  |   3

但这会导致

SELECT
  id,
  CASE WHEN seq = MIN(seq) THEN task AS start,
  CASE WHEN seq = MAX(seq) THEN task AS end
FROM table
GROUP BY id;

但是我不想按ERROR: column "seq" must appear in the GROUP BY clause or be used in an aggregate function 分组

3 个答案:

答案 0 :(得分:2)

一种方法使用数组:

SELECT id, 
       (ARRAY_AGG(task ORDER BY seq ASC))[1] as start_task,
       (ARRAY_AGG(task ORDER BY seq DESC))[1] as end_task
FROM table
GROUP BY id;

另一种方法将窗口函数与SELECT DISTINCT一起使用:

select distinct id,
       first_value(task) over (partition by id order by seq) as start_task,
       first_value(task) over (partition by id order by seq desc) as end_task
from t;

答案 1 :(得分:0)

您可以将窗口函数用于派生表:

select id, task, min_seq as start, max_seq as "end"
from (
  select id, task, seq, 
         max(seq) over (partition by id) as max_seq,
         min(seq) over (partition by id) as min_seq
  from the_table
) t
where seq in (max_seq, min_seq)

答案 2 :(得分:0)

这里的一种选择是将ROW_NUMBER与聚合和数据透视逻辑一起使用:

WITH cte AS (
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY seq) rn_min,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY seq DESC) rn_max
    FROM yourTable
)

SELECT
    id,
    MAX(CASE WHEN rn_min = 1 THEN task END) AS start,
    MAX(CASE WHEN rn_max = 1 THEN task END) AS end
FROM cte
GROUP BY
    id;

screen capture from demo link below

Demo