気になったのでテーブルを正規化してみました。
saziさんのコードを借用しました。
SQL
1CREATE TABLE tbl
2 (cd varchar2(2), sub_cd varchar2(3))
3;
4INSERT ALL
5 INTO tbl (cd, sub_cd)
6 VALUES ('A1', '111')
7 INTO tbl (cd, sub_cd)
8 VALUES ('A1', '222')
9 INTO tbl (cd, sub_cd)
10 VALUES ('A1', '333')
11 INTO tbl (cd, sub_cd)
12 VALUES ('A2', '222')
13 INTO tbl (cd, sub_cd)
14 VALUES ('A2', '444')
15 INTO tbl (cd, sub_cd)
16 VALUES ('A3', '222')
17SELECT * FROM dual
18;
19COMMIT ;
SQL
1select listagg(B.cd || ',' || B.sub_cd, ',') within group(order by B.cd) AS sub_cd -- cd と sub_cd を1行にまとめる
2FROM(
3 select A.cd, listagg(A.sub_cd, ',') within group(order by A.sub_cd) AS sub_cd -- 同一cd の sub_cd を1行にまとめる
4 FROM(
5 SELECT ROW_NUMBER() OVER(PARTITION BY sub_cd ORDER BY cd) AS RN
6 , cd
7 , sub_cd
8 from tbl
9 ) A
10 where A.RN = 1 -- 重複する sub_cd を除く
11 GROUP BY A.cd
12 ORDER BY A.cd
13 ) B ;
SUB_CD
---------------------
A1,111,222,333,A2,444
もっとシンプルになるかと思っていたんですが、最終的に横に1行で並べるのが面倒ですね。
パフォーマンス・チューニングに呼ばれると正規化がきちんとできていると10時間かかっていた処理を1時間にできることもありますし、正規化がズタズタだとテーブルをきちんと正規化しないとまともにチューニングできず、正規化すると莫大な費用がかかるのでほとんど成果をだせないこともあります。