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');