I have the following two tables:
# select * from list;
list_id | name
---------+----------------------
9 | Popular
11 | Recommended
and
# select * from list_item;
list_id | game_id | position
---------+---------+----------
11 | 2 | 0
9 | 10 | 1
11 | 5 | 1
11 | 4 | 4
11 | 6 | 2
11 | 7 | 3
9 | 3 | 0
I want an array of game IDs per list like so:
list_id | name | game_ids
---------+-------------+------------
9 | Popular | {3,10}
11 | Recommended | {2,5,6,7,4}
I came up with the following solution but it seems rather complicated especially the bit where I get the completed array using distinct on
and last_value
:
with w as (
select
list_id,
name,
array_agg(game_id) over (partition by list_id order by position)
from list
join list_item
using (list_id)
)
select
distinct on (list_id)
list_id,
name,
last_value(array_agg) over (partition by list_id)
from w
Any suggestions how to simplify this?
PostgreSQL ARRAY_AGG() function is an aggregate function that accepts a set of values and returns an array where each value in the input set is assigned to an element of the array. Syntax: ARRAY_AGG(expression [ORDER BY [sort_expression {ASC | DESC}], [...]) The ORDER BY clause is an voluntary clause.
To define a new aggregate function, one selects a data type for the state value, an initial value for the state, and a state transition function. The state transition function takes the previous state value and the aggregate's input value(s) for the current row, and returns a new state value.
The coalesce function can be used to substitute zero or an empty array for null when necessary. Here ANY can be considered either as introducing a subquery, or as being an aggregate function, if the subquery returns one row with a Boolean value.
The jsonb_agg(expression) function aggregates all values indicated by its expression, returning the values (including nulls) as a jsonb array.
Here is a better solution as suggested by Abelisto in the comments:
select
list_id,
name,
array_agg(game_id order by position)
from list
join list_item
using (list_id)
group by list_id, name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With