Skip to content
Advertisement

PostgreSQL group by column with aggregate

I need to group by id and select the task with min/max seq as start and 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;

But this results in

ERROR:  column "seq" must appear in the GROUP BY clause or be used in an aggregate function

But I do not want group by seq

Advertisement

Answer

One method uses arrays:

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;

Another method uses window functions with 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;
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement