UNION ALL
UNION ALL
で「カウンターピボット」することができます 最初:
SELECT name, array_agg(c) AS c_arr
FROM (
SELECT name, id, 1 AS rnk, col1 AS c FROM tbl
UNION ALL
SELECT name, id, 2, col2 FROM tbl
ORDER BY name, id, rnk
) sub
GROUP BY 1;
後で要求した値の順序を生成するように適合されています。 マニュアル:
大胆な強調鉱山。
LATERAL
サブクエリ
VALUES
を使用 式
LATERAL
Postgres 9.3が必要です またはそれ以降。
SELECT t.name, array_agg(c) AS c_arr
FROM (SELECT * FROM tbl ORDER BY name, id) t
CROSS JOIN LATERAL (VALUES (t.col1), (t.col2)) v(c)
GROUP BY 1;
同じ結果。テーブルを1回パスするだけで済みます。
カスタム集計関数
または これらの関連する回答で説明されているようなカスタム集計関数を作成できます:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
次に、次のことができます。
SELECT name, array_agg_mult(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
または、通常は高速ですが、標準のSQLではありません:
SELECT name, array_agg_mult(ARRAY[col1, col2]) AS c_arr
FROM (SELECT * FROM tbl ORDER BY name, id) t
GROUP BY 1;
追加されたORDER BY id
(このような集計関数に追加できます)は、目的の結果を保証します:
a | {1,2,3,4}
b | {5,6,7,8}
または、この代替案に興味があるかもしれません:
SELECT name, array_agg_mult(ARRAY[ARRAY[col1, col2]] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
2次元配列を生成します:
a | {{1,2},{3,4}}
b | {{5,6},{7,8}}
最後のものは、組み込みのarray_agg()
に置き換えることができます(そして、より高速であるため、そうする必要があります!)。 Postgres 9.5 またはそれ以降-配列を集約する機能が追加されました:
SELECT name, array_agg(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
同じ結果。 マニュアル:
したがって、カスタム集計関数array_agg_mult()
とまったく同じではありません。;