SQLのSTRING_AGGで複数レコードの内容を1カラムに出す

この記事は約2分で読めます。

SQL Serverの場合、FOR XML PATH を使うと、あるカラムの複数レコードのデータを結合できます。
が、XMLの名前のとおり、本来の使用用途とは違うので違和感がありました。(XMLを生成する目的なら問題ない)

目的に合致した関数があるはず、と探したところ、STRING_AGG という関数が使えるようです。
(ちなみに、MySQLではGROUP_CONCAT関数、OracleではLISTAGG関数で同様の処理ができます。RDBMS毎の方言ですね)

SELECT
    code
   ,item
   ,cate
   ,STRING_AGG(memo, ',') AS MEMO
FROM     Table_B
GROUP BY code, item, cate
;

以下は解説です。


例えば、次のようなデータがあったとします。

code | item | cate | suryo | kingaku | memo
A01 | G001 | 11 | 50 | 1000 | aa
A01 | G001 | 11 | 30 | 1500 | aa
A01 | G001 | 11 | 10 | 1300 | aa
A01 | G001 | 12 | 60 | 2100 | aa
B01 | G001 | 11 | 20 | 1600 | bb
B01 | G001 | 12 | 40 | 3500 | cc
B01 | H001 | 11 | 35 | 3000 | dd
B01 | H001 | 11 | 15 | 1200 | ee
B02 | H001 | 12 | 70 | 1400 | ff
B02 | H001 | 12 | 80 | 2300 | gg

ここに冒頭のようなSQLを流すと、結果はこのようになります。

code | item | cate | MEMO
A01 | G001 | 11 | aa,aa,aa
A01 | G001 | 12 | aa
B01 | G001 | 11 | bb
B01 | G001 | 12 | cc
B01 | H001 | 11 | dd,ee
B02 | H001 | 12 | ff,gg

可能ならば、MEMO内の重複を除去したいのです。
(このサンプルなら、最初の行の「aa,aa,aa」を「aa」にしたい)
DISTINCTとか色々試したのですが、上手い方法が見つかりませんでした。

参考文献:Microsoft SQLドキュメント

タイトルとURLをコピーしました