PostgreSQL

PostgreSQL 複数行の値を1行でまとめて表示する

group by で指定するグループ内の複数項目を指定順番に連結し表示する。OracleではLISTAGG()関数が用意されていますが、これをPostgreSQLでは2つの関数を組み合わせて実現できます。

array_agg()で配列化した後to_string()で文字列化
select pcname,array_to_string(array_agg(spec_name),'/')
from note_pc group by pcname
;
-- 以下のようなデータがあります。
myposdb=# select * from note_pc;
    pcname    | spec_key |   spec_name
--------------+----------+----------------
 FMV LIFEBOOK | CPU      | Core i5 10210U
 ThinkBook 14 | CPU      | Core i5 1235U
 LAVIE N15    | CPU      | Ryzen 5 4500U
 FMV LIFEBOOK | core     | 4コア
 ThinkBook 14 | core     | 10コア 1235U
 LAVIE N15    | core     | 6コア
 FMV LIFEBOOK | メモリ   | 8G
 ThinkBook 14 | メモリ   | 16G
 LAVIE N15    | メモリ   | 8G
(9 rows)

-- 複数行の値を1行にまとめる
myposdb=# select pcname,array_to_string(array_agg(spec_name),'/')
myposdb-# from note_pc group by pcname
myposdb-# ;
    pcname    |        array_to_string
--------------+--------------------------------
 FMV LIFEBOOK | Core i5 10210U/4コア/8G
 ThinkBook 14 | Core i5 1235U/10コア 1235U/16G
 LAVIE N15    | Ryzen 5 4500U/6コア/8G
(3 rows)


myposdb=# 

解説

-- array_agg()は複数行を配列に入れます。
myposdb=# select pcname,array_agg(spec_key) spec_key,array_agg(spec_name) spec_name
myposdb-# from note_pc group by pcname
myposdb-# ;
    pcname    |     spec_key      |              spec_name
--------------+-------------------+--------------------------------------
 FMV LIFEBOOK | {CPU,core,メモリ} | {"Core i5 10210U",4コア,8G}
 ThinkBook 14 | {CPU,core,メモリ} | {"Core i5 1235U","10コア 1235U",16G}
 LAVIE N15    | {CPU,core,メモリ} | {"Ryzen 5 4500U",6コア,8G}
(3 rows)

-- array_to_string()は配列を指定の区切り文字でSTRINGに変換します。
-- 区切り文字が不要の場合''とします
myposdb=# select pcname
myposdb-# ,array_to_string(array_agg(spec_key),'')  spec_key
myposdb-# ,array_to_string(array_agg(spec_name),',')  spec_name
myposdb-# from note_pc group by pcname
myposdb-# ;
    pcname    |   spec_key    |           spec_name
--------------+---------------+--------------------------------
 FMV LIFEBOOK | CPUcoreメモリ | Core i5 10210U,4コア,8G
 ThinkBook 14 | CPUcoreメモリ | Core i5 1235U,10コア 1235U,16G
 LAVIE N15    | CPUcoreメモリ | Ryzen 5 4500U,6コア,8G
(3 rows)


myposdb=#

検証データ

-- テーブル
create table note_pc
(
 pcname varchar(20)
,spec_key varchar(20)
,spec_name varchar(20)
);

-- テストデータ
insert into note_pc(pcname,spec_key,spec_name) values ('FMV LIFEBOOK','CPU','Core i5 10210U');
insert into note_pc(pcname,spec_key,spec_name) values ('ThinkBook 14','CPU','Core i5 1235U');
insert into note_pc(pcname,spec_key,spec_name) values ('LAVIE N15','CPU','Ryzen 5 4500U');
insert into note_pc(pcname,spec_key,spec_name) values ('FMV LIFEBOOK','core','4コア');
insert into note_pc(pcname,spec_key,spec_name) values ('ThinkBook 14','core','10コア 1235U');
insert into note_pc(pcname,spec_key,spec_name) values ('LAVIE N15','core','6コア');
insert into note_pc(pcname,spec_key,spec_name) values ('FMV LIFEBOOK','メモリ','8G');
insert into note_pc(pcname,spec_key,spec_name) values ('ThinkBook 14','メモリ','16G');
insert into note_pc(pcname,spec_key,spec_name) values ('LAVIE N15','メモリ','8G');
Oracle版はこちら
スポンサーリンク