データベース千夜一夜第5回

条件指定によるレコードの絞り込み(2)
~範囲を指定しての比較、文字列の比較
長谷川裕行
有限会社 手國堂

「_」記号の特殊な用法

任意の1文字を指定するワイルドカード「_」記号には、単純なあいまい検索の他にも面白い使い方があります。


- 文字数が明確なフィールドに対して使う -

LIKE演算子のワイルドカードで任意の1文字を指定する「_」記号は、通常、フィールド内の文字数(桁数)が明確になっている場合に役立ちます。例えば「得意先_mr」テーブルで「郵便番号が60で始まる地域(京都府)」のレコードだけを抽出するなら、以下のようなSQLを記述します。

  SELECT * FROM 得意先_mr WHERE 郵便番号 LIKE '60_-____'

郵便番号は“xxx-xxxx”と、上3文字と下4文字が「-」がつながれた形式なので、上記のように「_」で文字数を明確に指定できます。電話番号で特定の市外局番のレコードを抜き出す場合も同じ要領です。

商品番号などの識別記号を数値ではなく文字列で設定していて、先頭の2桁が国コード、続く3桁がメーカーコード……などとなっている場合(バーコードなど)、「_」で特定のメーカーの商品だけを抽出することも可能です。




- 指定した文字数のデータを探す -

「1文字を指定する」という機能を持つ「_」記号は、上に示したような文字数の明確になっているフィールドに対してだけではなく、文字数がまちまちなフィールドに対しても使えます。文字列の内容ではなく「格納されている値(文字列)が何文字か」を指定できるためです。

例えば以下のようなSQLを記述すれば、「得意先_mr」テーブルから「氏名の文字数が5文字の人」だけを抜き出せます。

  SELECT * FROM 得意先_mr WHERE
            氏名 LIKE '_____'
                   ↑アンダースコア5個
 (レイアウトの都合上、改行して表記されています)




- 可変長と固定長による違い -

文字列を格納するデータ型には、可変長(varchar/nvarchar型)と固定長(char/nchar型)の2種類があります。可変長ではフィールドに入力された値の文字数がそのまま文字数として認識されますが、固定長の場合は予め確保した桁数(バイト数)の分スペースで埋められるため、「_」による文字数の指定結果が異なります。

「氏名」フィールドをvarchar(20)とした場合とchar(20)とした場合で比べてみましょう。このフィールドに“山田源五郎”という文字列が入っていたとします。

  a) varchar(20)のとき “山田源五郎”
  b) char(20)のとき “山田源五郎__________”
                       ↑10個分の半角スペース

「_」は半角/全角の区別なく「1文字」に合致するので、a)の場合は“_____”(「_」5個分)となりますが、b)の場合は“_______________”(「_」15個分)となります。つまり、全角の“山田源五郎”で5文字+残りの半角スペース10文字=15文字――ということです。


- 全角文字と半角スペースに注意 -

格納されている文字列が“山田源五郎”ではなく“山田五郎”だったら、a)の場合は“____”(「_」4個分)、b)の場合は「________________」(「_」16個分=全角4文字+残りの半角スペース12個)となります。予め埋められている半角スペースは2文字で全角1文字と置き換えられますが、残りはそのまま半角スペース1個が1文字分となるため、格納されている全角文字の数によって全体の文字数が変わってしまうのです。

日本語を扱う処理にとって、全角/半角の区別なく1文字と見なされる仕様は一見便利なようですが、固定長のデータ型では文字数を数える場合に混乱を来す原因ともなります。基本的に固定長の文字列は、コード番号などすべてが半角文字のフィールドだけを対象とした方がよいでしょう。


あとがき

レコードを絞り込むWHERE句の条件式は、使用頻度の高い非常に重要な機能です。データ型による挙動の違いなど厄介な問題はありますが、しっかり理解して使いこなしてください。サンプル・データベースとサンプルを使って、いろいろなSQLを試してみることをお勧めします。


Downloadサンプルファイル (LZH形式 1.61 KB)


トップページ
値の範囲や文字列の比較を行う演算子
LIKE演算子とワイルドカード
「_」記号の特殊な用法
文字数が明確なフィールドに対して使う
指定した文字数のデータを探す
可変長と固定長による違い
全角文字と半角スペースに注意
あとがき
Copyright © MESCIUS inc. All rights reserved.