MySQL_8.4のREGEXP_LIKE関数を使ったデータ検索

目次

はじめに

MySQLでは文字列検索を行う際に、LIKE句を利用することがよくあります。
例えば、名前に「SQL」を含むデータを検索する場合は以下のように記述できます。

LIKE句はシンプルで使いやすい反面…
・ 電話番号の形式を検証したい
・ メールアドレスの形式を確認したい
・ 複数キーワードのいずれかにマッチするか調べたい
・ 特定の桁数や文字種で構成されているか確認したい

…といったケースでは表現力に限界があります。

このような場合に活躍するのが REGEXP_LIKE関数 です。
MySQL 8.4では、ICU(International Components for Unicode)ライブラリを利用した高機能な正規表現エンジンが利用でき、柔軟な文字列検索が可能になっています。

参照:MySQL 8.4 Reference Manual – 14.8.2 Regular Expressions
MySQL implements regular expression support using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe.

今回はREGEXP_LIKE関数の基本的な使い方から、実践例まで紹介していきます。

REGEXP_LIKE関数の基本構文

REGEXP_LIKE関数の構文を下記に記載します。 構文自体はとてもシンプルなので、関数として利用しやすい印象を受けます!

・ expression: 検索対象の文字列
・ pattern: 正規表現パターン
・ match_type: オプション(省略可)

match_typeオプションについて

オプション 説明
i 大文字小文字を区別しない
c 大文字小文字を区別する
m 複数行モード
n . が改行文字にもマッチするようになる

複数のオプションを同時に指定することも可能です。例えば 'im' を指定すると、大文字小文字を区別せず、かつ複数行モードで照合します。

参照:MySQL 8.4 Reference Manual – 14.8.2 Regular Expressions
“If characters specifying contradictory options are specified within match_type, the rightmost one takes precedence.”

データ準備

今回は「スーパーヒーロー人材派遣会社」のデータを使用します! AI時代の到来と共にデータベースの重要性が増した世界。データを操る能力を持つスーパーヒーローたちが、人類のデジタル社会を守るため立ち上がりました!!

…という構想です。

スーパーヒーローたちにも得意、不得意分野が少なからずあると思い、 そういった情報も登録していますが…
果たしてREGEXP_LIKE関数とのコラボはあるのか… 本ブログを最後までご覧ください!

REGEXP_LIKE関数の使い方

ケース1:基本的なパターンマッチング

まずは基本的な使い方から見てみましょう。
ヒーロー名に「SQL」を含むデータを検索してみます。

次に'i'フラグを指定し、大文字小文字を区別せずに検索します。

続いて | を使ったOR検索です。「王」または「姫」を含むヒーローを絞り込みます。
以下のようにLIKEで同じ条件を書くと OR を複数つなぐ必要がありますが、REGEXP_LIKE関数ならパターン1つで完結することがわかります。

ケース2:電話番号のマッチング検索

次に電話番号の形式を検証してみましょう。
SELECT句にis_valid_phoneを表示しており、一目で確認できるようにしています。

(補足)正規表現パターン解説:
^: 行の開始
[0-9]{2,3}: 数字が2-3桁
-: ハイフン(リテラル)
[0-9]{4}: 数字がちょうど4桁
$: 行の終了

ケース3:メールアドレスの検証とドメイン分析

電話番号のチェックだけでなく、メールアドレスの形式チェックや解析も可能です。
CASEと組み合わせることにより、条件分岐が可能となりますので幅広く活用することができます!

(補足)メール検証パターンの詳細解説:
^[a-zA-Z0-9._%+-]+: ローカル部(@より前)
@: アットマーク
[a-zA-Z0-9.-]+: ドメイン名部分
[a-zA-Z]{2,}$: トップレベルドメイン(2文字以上)
\.: ドット(エスケープ必須)

⚠️ 重要: 正規表現での「\」は「ドット(.)」をリテラル文字として扱うためのエスケープ文字です。 「.」だけの場合は「任意の1文字」という意味になってしまいます!

ケース4:日付パターンの検索

MySQLで特定の年を抽出する場合、YEAR関数やDATE_FORMAT関数を使用するケースもあると思いますが、こういった関数を使用せずに抽出することが可能です。

また、以下のように特定の月だけ抽出することもできます!

ケース5:リスク分析

業務によっては、特定のワード、数値でリスク分析を行うこともあると思いますが、
このような場合においても、CASEとREGEXP_LIKE関数が活用できます!

ケース6:アンマッチデータの検索

REGEXP_LIKE関数を利用して、パターンに一致しないデータ(アンマッチデータ)を検索したい場合、NULL値の扱いに注意が必要です。

例えば、電話番号が正しい形式ではないデータを抽出したいとします。
今回は、以下の3件が抽出されることを期待します。

まず失敗例は以下の通りです。
NOT演算子+REGEXP_LIKE関数を使っていますが、NULL値が抽出されていません。
なぜNULL値は抽出されないのでしょうか?

REGEXP_LIKE関数は、検索対象またはパターンがNULL値の場合、戻り値としてNULL値を返します。MySQLリファレンスマニュアルにも次のように記載されています。

参照:MySQL 8.4 Reference Manual – 14.8.2 Regular Expressions

“Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise. If expr or pat is NULL, the return value is NULL.”

つまり、電話番号がNULLの場合、
REGEXP_LIKE(NULL, '^[0-9]{2,3}-[0-9]{4}-[0-9]{4}$')
の結果(戻り値)は NULL値となります。

さらに、NOT演算子でNULL値の結果を判定すると NOT NULLはNULL値になります。
そのため、

REGEXP_LIKEの結果 NOT演算後 WHERE句で抽出されるか
1 0 ×
0 1
NULL NULL ×

…となり、NULL値は抽出されません。

これはSQLが採用している 三値論理(TRUE / FALSE / UNKNOWN)による動作です。
なおNULL値も不正データとして扱いたい場合は、 IS NULLIS UNKNOWNを組み合わせることで抽出可能です。

またCOALESCE関数を上手く使うことで、
以下のようにマッチ/アンマッチデータにNULL値を含めることができます!!

データ品質チェックでは、フォーマットエラーだけでなくNULL値も異常データとして扱うケースが多いため、この書き方を覚えておくと実務でも役立ちます。

なおNULL値の扱い方は、「MySQLのNULL値の扱い方について」というブログでも紹介していますので、是非ご参考にしてください。

まとめ

今回はMySQL 8.4で利用できるREGEXP_LIKE関数を紹介しました。

REGEXP_LIKE関数を利用することで、
・ 電話番号形式のチェック
・ メールアドレスの検証
・ 日付けパターンの検索
・ リスク分析
・ アンマッチデータの検索
など、LIKE句だけでは実現が難しい検索処理を簡潔に記述できます。

一方で、インデックスが利用されないケースもあるため、大量データに対して利用する場合はパフォーマンスにも注意が必要です。
正規表現を活用することで、SQLによるデータ検索やデータ品質管理の幅が大きく広がります。ぜひ業務でも活用してみてください。

スマートスタイルTECHブログについて

スマートスタイルTECHブログでは、日頃MySQLのサポート業務に従事している有資格者で構成された技術サポートチームがMySQLに関する技術情報を発信しています。データベースのお困りごとはお気軽にご相談下さい。

よかったらシェアしてね!
  • URLをコピーしました!
目次