2016-08-08 8 views
0

Ich habe in den folgenden beiden Tabellen:Postgres: Aggregatspalte in Array

# select * from list; 
    list_id |   name 
---------+---------------------- 
     9 | Popular 
     11 | Recommended 

und

# 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 

Ich möchte eine Reihe von Spiele-IDs pro Liste wie folgt:

list_id |  name | game_ids 
---------+-------------+------------ 
     9 | Popular  | {3,10} 
     11 | Recommended | {2,5,6,7,4} 

Ich kam zu der folgenden Lösung, aber es scheint ziemlich kompliziert, vor allem das Bit, wo ich das fertige Array mitund 0 bekomme:

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 

Irgendwelche Vorschläge, wie dies zu vereinfachen?

+0

Ist es eine Anforderung, eine Fensterfunktion zu benutzen? –

+0

Wenn Ihr Problem in 'order by' ist, können Sie es für einige Aggregatfunktionen aggregieren, also:' Wählen Sie list_id, name, array_agg (game_id order by position) aus der Liste join list_item mit (list_id) group by list_id, name ; 'sollte genug sein. – Abelisto

+0

@AlexanderGuz Nein, es ist keine Voraussetzung, Fenster zu verwenden. Tut mir leid, hätte das deutlicher machen sollen. – peterwimsey

Antwort

2

Hier ist eine bessere Lösung als durch Abelisto in den Kommentaren vorgeschlagen:

select 
    list_id, 
    name, 
    array_agg(game_id order by position) 
from list 
join list_item 
using (list_id) 
group by list_id, name