文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

MySQLで複数レコードからカンマ区切りの結合文字列を生成する

複数のカラムをカンマ区切りで結合するケース、よくありますよね。


f:id:treeapps:20180418131549p:plain

今回はmysqlで実装してみます。

非常に簡単です。concat_wsを使うだけです。

mysql> select concat_ws (',', 'aaa', '', 'bbb', null, 'ccc');
+------------------------------------------------+
| concat_ws (',', 'aaa', '', 'bbb', null, 'ccc') |
+------------------------------------------------+
| aaa,,bbb,ccc                                   |
+------------------------------------------------+

第一引数がデリミタです。
concat_wsはconcatと違い、nullが混入してもnullは返りません。
↑のようにnullをバッチリ無視してくれます!しかし、空文字は突破されますね。では、

mysql> select concat_ws (',', nullif('aaa', ''), nullif('', ''), nullif('bbb', ''), nullif(null, ''), nullif('ccc', ''));
+------------------------------------------------------------------------------------------------------------+
| concat_ws (',', nullif('aaa', ''), nullif('', ''), nullif('bbb', ''), nullif(null, ''), nullif('ccc', '')) |
+------------------------------------------------------------------------------------------------------------+
| aaa,bbb,ccc                                                                                                |
+------------------------------------------------------------------------------------------------------------+

ちょっと冗長ですが、nullifすれば空文字も対処できます。

よくある利用ケースは、複数のカラムをconcat_wsで1カラムにまとめ、アプリ側でsplitするような場合ですね。

1カラムにまとめてしまうことで、例えば名称等、同系統のカラムが100個有った場合、concat_wsで1カラムにまとめてしまえば、アプリ側(例えばjspで)splitして<c:forEach>させればnullチェックは不要だし、要素の中身を気にしなくてもよくなります。

他の利用ケースとして、ストアドプロシージャでも使えます。

例えば、チェックボックスでチェックされた場合のみ、WHERE句にAND条件追加、とか。文字列でWHERE句の条件を作っておき、

concat_ws ('and ', nullif(condition1, ''), nullif(condition2, ''), nullif(condition3, ''))

とかやれば、動的な条件も最小限のコードで書くことができちゃいます。これは便利。