web-dev-qa-db-ja.com

Postgres-2つの列を1つのアイテムに集約

グループ化するときに、2つの列を1つの「配列」に集約したいと思います。

次のようなテーブルを想定します。

friends_map:
=================================
user_id    friend_id    confirmed
=================================
1          2            true
1          3            false
2          1            true
2          3            true
1          4            false

このテーブルから選択し、user_idでグループ化し、friend_idを取得し、コンマで区切られた連結値として確認します。

現在、私はこれを持っています:

SELECT user_id, array_agg(friend_id) as friends, array_agg(confirmed) as confirmed
FROM friend_map
WHERE user_id = 1
GROUP BY user_id

私を取得します:

=================================
user_id    friends      confirmed
=================================
1         [2,3,4]       [t, f, f]

どうすれば入手することができますか:

=================================
user_id    friends     
=================================
1         [ [2,t], [3,f], [4,f] ]
25
SoluableNonagon

array_agg()関数に渡す前に、値を連結できます。

SELECT user_id, array_agg('[' || friend_id || ',' || confirmed || ']') as friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id

デモ: SQL Fiddle

24
Hart CO
SELECT user_id, array_agg((friend_id, confirmed)) as friends
FROM friend_map
WHERE user_id = 1
GROUP BY user_id

user_id |           array_agg            
--------+--------------------------------
      1 | {"(2,true)","(3,false)","(4,false)"}
38
Ivan Burlutskiy

多次元配列のさを避け、混合データ型をサポートするjsonを使用できます。

SELECT user_id, json_agg(json_build_array(friend_id, confirmed)) AS friends 
    FROM friends_map 
    WHERE user_id = 1
    GROUP BY user_id

または、key : valueはjsonで許可されているためペアになります。したがって、出力はsemanticになります。

SELECT user_id, json_agg(json_build_object(
        'friend_id', friend_id, 
        'confirmed', confirmed
    )) AS friends 
    FROM friends_map 
    WHERE user_id = 1
    GROUP BY user_id;
30
Eggplant

Postgres 9.5では、テキストの配列の配列を取得できます。

SELECT user_id, array_agg(array[friend_id::text, confirmed::text])
FROM friend_map
WHERE user_id = 1
GROUP BY user_id;

 user_id |           array_agg            
---------+--------------------------------
       1 | {{2,true},{3,false},{4,false}}
(1 row)

またはintの配列の配列:

SELECT user_id, array_agg(array[friend_id, confirmed::int])
FROM friend_map
WHERE user_id = 1
GROUP BY user_id;

 user_id |      array_agg      
---------+---------------------
       1 | {{2,1},{3,0},{4,0}}
(1 row) 
13
klin