パターンマッチングで比較
WHERE句で条件を指定する場合に、カラムの値と文字列の値をワイルドカードを使ったパターンマッチングする場合に使用するのがLIKE演算子です。書式は次の通りです。
WHERE col_name LIKE pattern
WHERE col_name NOT LIKE pattern
2つのワイルドカードを使った簡単なパターンマッチングを行います。カラムの値がマッチすれば1(=TRUE)を返します。それ以外は0を返します。NOT LIKEの場合は、LIKEの結果を反転した結果(1なら0、0なら1)となります。
※ カラムの値又はパターンがNULLの場合はNULLを返します。
ワイルドカードとして使用できるのは次の2文字です。
% 任意の0文字以上の文字列 _ 任意の1文字
'_'は任意の1文字にマッチします。
___ 3文字の任意の文字列 a__b aで始まりbで終わる4文字の文字列
'%'は0文字以上の任意の文字列にマッチします。
sql% sqlで始まる任意の長さの文字列 a%b aで始まりbで終わる任意の長さの文字列 a_%b aで始まりbで終わる3文字以上の任意の長さの文字列
例えば次のように記述します。
SELECT * FROM books WHERE name LIKE '%java%';
上記では「name」カラムの値に'java'が含まれるデータを取得します。
エスケープ処理
ワイルドカード文字列を'%'や'_'という文字としてマッチさせたい場合には'¥'文字を使ってエスケープを行います。
¥% ¥_
ワイルドカード文字列を'%'や'_'という文字としてマッチさせたい場合には'¥'文字を使ってエスケープを行います。また'¥'はエスケープの為の文字として使用されるため、'¥'を文字としてマッチさせたい場合にもエスケープを行います。
¥¥
パターンをまずこのようにエスケープしたら、パターンは文字列として指定するため今度は文字列に対する必要なエスケープを行います。文字列に対するエスケープ処理は「文字列リテラル」を参照して下さい。
例えば文字としての'¥'にマッチさせるパターンは、まず'¥'をパターンとしてエスケープして'¥¥'とします。次に文字列としてエスケープするため'¥'一文字に付き'¥¥'とするため結果的に'¥¥¥¥'と記述することになります。
なおパターンの方のエスケープする文字はデフォルトで'¥'ですが、ESCAPE句を使うと違う文字をエスケープ用文字として指定できます。書式は次の通りです。
WHERE col_name LIKE pattern ESCAPE 'escape_char'
例えば次のように記述します。
SELECT * FROM css WHERE tagname LIKE 'border$_%' ESCAPE '$';
上記の場合は'_'をエスケープするのに'$'を使って'$_'と記述しています。
BINARY演算子
文字列比較の時、デフォルトでは大文字と小文字を区別しません。区別を行いたい場合はBINARY演算子を指定します。
WHERE col_name LIKE BINARY pattern
例えば次のように記述します。
SELECT * FROM personal WHERE address LIKE BINARY 'Tokyo%';
上記の場合は「address」カラムの値が'Tokyo'で始まっているデータにはマッチしますが'tokyo'で始まっている文字列にはマッチしません。
サンプル
実際に試してみます。まず次のようなテーブルを作成します。
mysql> create table personal(name varchar(20), hobbies varchar(20));
テーブルには次のようなデータを追加してあります。
では「hobbies」カラムに'Movie'が含まれるデータを取得します。
mysql> select * from personal where hobbies like '%Movie%';
反対に「hobbies」カラムに'Movie'が含まれないデータを取得します。
mysql> select * from personal where hobbies not like '%Movie%';
なおデフォルトではパターンに'%Movie%'と指定すると大文字と小文字が区別されずにマッチします。その為'Movie'であっても'movie'であっても'MOVIE'であってもマッチします。ではBINARY演算子を使って大文字小文字を区別してマッチさせてみます。
mysql> select * from personal where hobbies like binary '%Movie%';
このように「hobbies」カラムの値が'Sports, Movie'にはマッチしましたが'movie, drive'にはマッチしませんでした。
( Written by Tatsuo Ikura )