挨拶
初めまして、日本システム開発株式会社の鈴木です。
技術者として更なる向上を目指すためQiitaアウトプットをする取り組みを行っています。
技術者としては経験が浅く発信内容はとにかく試したものの覚書になります。
今回はSQLServerにてSELECT文内で特定の区切り文字を含むカラムについて、2番目の区切り文字から固定数の区間を切り出す方法について記載します。
やりたいこと
以下のように、特定の区切り文字('-')を複数もち区切り内の桁数が4桁固定である値を含むカラムが存在するとします。
0123-4567-8901
1234-1098-4321-1234
ABCD-EFGH-IJKL
...
このような列の中から3番目の区切りを抽出し以下のようなカラムとして射影します。
8901
4321
IJKL
...
対応
最終的には以下のようなSELECT文を発行し対応しました。
SELECT SUBSTRING(columnA,CHARINDEX('-',columnA,CHARINDEX('-',columnA)+1)+1,4);
以下の2関数を利用して2番目の区切り文字の出現位置から4文字を切り出しています。
---文字の切り抜き
SUBSTRING(切り出し元カラム,開始位置、切り出し文字数)
---区切り文字の出現位置取得
CHARINDEX(検索文字,検索先カラム,検索開始位置)
※検索開始位置は省略した場合0(先頭から)
まずCHARINDEX('-',columnA)+1
で1つ目の区切り文字の1文字あとを検索します。
検索した位置から4文字を取得することで2番目の区間を切り出すことができます。
SELECT SUBSTRING(columnA,CHARINDEX('-',columnA)+1,4);
4567
1098
EFGH
...
しかし今回は2つ目の区切り文字から文字の切り出しを行いたいため、CHARINDEX()の検索開始位置を1つ目の区切り文字の1文字あとに指定する必要があります。つまり
CHARINDEX('-',columnA,CHARINDEX('-',columnA)+1)+1)
のように開始位置に1つ目の区切り文字の1文字あとを設定した上でもう一度区切り文字の開始位置を検索することで2つ目の区切り文字の位置を検索することができます。
おわりに
本稿では特定の文字で区切られたカラムに対し3つめの区域を切り出すSQLについてまとめました。ただし、N番目の区域を切り出すためにはN-2回の繰り返し処理が必要になるため、処理の負荷が高くなることが懸念されるだけでなく、可読性も悪いです。単純に値として欲しいだけならSQLによる取得後に分割処理を別に設けた方がよいでしょう。今回は3つ目の区域の値を利用して抽出カラムを指定する必要がありこのような形になりました。
備考
本稿はSQLServerにて特定文字のN番目の出現位置を取得するSQLを作成しましたが、MySQLでは指定文字列が指定回数出現するまでの文字列を切り出すSUBSTRING_INDEX()関数があるそうです。MySQL環境ではそちらを使った方が無難でしょう。