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

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

値の範囲や文字列の比較を行う演算子

条件式に設定するデータの比較では、単に値の大小関係以外にも、様々な状態と関係が存在します。それらもまた、比較演算子を使って判定できます。


- 値の大小関係以外の比較 -

比較演算子には、数値を比較する演算子の他に表1に示すような4種類があります。他にも、もっと複雑な条件式で用いる演算子がありますが、それらについては回を追って紹介します。ここでは、比較的単純な条件式で用いるものだけを取り上げます。

表を見れば分かるように、これらの演算子は単純な値の大小ではなく、「値がある範囲に収まっているかどうか」や「文字列の一部が合致するかどうか」などを比較・判定します。

表1:値の大小関係以外の比較を行う演算子
演算子 機能
BETWEEN 値が指定した範囲内であれば「真」
IN 列挙した値のどれかと一致すれば「真」
LIKE 文字列中に合致するパターンが見つかれば「真」
IS NULL フィールドがNULL値※1のとき「真」
※1 何の値も設定されていない状態。数値の「0」や空文字列("")とは異なる

SQL Serverのデータ型

LIKE演算子は文字列を対象に値の比較(パターンマッチング)を行います。また、BETWEEN演算子では数値の他に日付/時刻型の値を扱って「期間」や「時間」を指定できます(データベース・エンジン内では日付/時刻型の値は数値として扱われるため、">"や"<="などの数値を対象とした演算子も使えます)。実際の処理では数値型だけではなく、このような様々なデータ型に対して比較演算を行うことになります。

表aに、SQL Serverで扱えるデータ型を掲げておきます。また、SQL-92で規定されている標準のデータ型識別子と互換性を保つため、表bのようなシノニムを定義して識別子を置き換えるようになっています。

表a:SQL Serverで扱えるデータ型
表b:データ型のシノニム


- 値の範囲を指定~BETWEEN -

BETWEEN演算子は、フィールドの値が指定した値の「範囲内に収まる」レコードだけを抽出します。

書式は以下の通りです。

  <フィールド> BETWEEN <値1> AND <値2>

<フィールド>の値が<値1>以上<値2>以下となっているレコードが抽出されます。

「商品_mr」テーブルから「在庫数が10~20のレコード」を抽出するなら、以下のように記述します。

  SELECT * FROM 商品_mr WHERE 在庫 BETWEEN 10 AND 20

SQL Serverクエリアナライザでの実行結果は、画面1のようになります。これは、以下のようにしても同じ結果が得られます。

  SELECT * FROM 商品_mr WHERE 在庫 >= 10 AND 在庫 <= 20

BETWEEN演算子は、AND演算子で「同じフィールドの値を比較する2つの条件式」を結んだものと同じ結果となります※2。しかしその場合、フィールド名が重複して式全体の意味が分かりにくくなります。範囲を示す場合は、同じフィールド名を2回記述するよりBETWEEN演算子を使った方が簡潔です。



※2 BETWEEN演算子に用いられるANDは、パラメータである2つの値を区切る役目をする記号であって、論理演算子のANDとは別物です


- 個別の値を指定~IN -

IN演算子は、フィールドの値が列挙した複数の値のうち「どれか1つと合致」するレコードを抽出します。

書式は以下の通りです。

  <フィールド> IN (値1, 値2,・・・)

<フィールド>の値が( )内にカンマ(,)で区切って列挙した値のどれかと合致するレコードが抽出されます。

「商品_mr」テーブルから「商品ID」が“550205”“551221”“620315”となっている商品を抽出するなら、SQLは以下のように記述します。

  SELECT * FROM 商品_mr WHERE 商品ID IN (550205, 551221, 620315)

条件として設定する値が10~20のように連続している場合はBETWEEN演算子、バラバラの場合はIN演算子を使うことになります。




- NUUL値を見つける~IS NULL -

IS NULL演算子は、フィールドの値が「NULLである」レコードだけを抽出します。NULLは数値の「0」や空文字列(' ')ではなく、「何も格納されていない状態」を表しています※3

NULL値が含まれているということは、そのレコードには値が「未入力/未設定」のフィールドがあることを意味します。サンプル・データベース中の「得意先_mr」は、顧客の氏名、住所、電話番号などのデータを記録した住所録です。このテーブルの中から「FAX番号」が未入力のレコードを探すなら、以下のようなSQLを記述します。

  SELECT * FROM 得意先_mr WHERE FAX IS NULL

このようにIS NULL演算子は、未処理/未入力のフィールドを持つレコードを探すときに役立ちます。但し、数値型のフィールドに「0」を設定したり、文字列型のフィールドに空文字列を設定するような処理を実行した後では、そのフィールドの値はNULLではなくなってしまいます。この点に注意しましょう。



間に“NOT”を入れて“IS NOT NULL”とすると、「NULLではない」という意味になり、指定したフィールドにNULL値以外の値が格納されているレコードが抽出されます。

以下のSQLは上記の逆――「FAX番号」が入力済みのレコードを抽出します。

  SELECT * FROM 得意先_mr WHERE FAX IS NOT NULL



※3 IS NULLと似た予約語に「IsNull関数」があります。これは、引数にフィールド名と値を与え、フィールドがNULL値だった場合に引数に指定した値を代入する――という処理を行うTransactSQLの関数で、演算子ではありません。演算子は“S”と“N”の間にスペースが入りますが、関数ではスペースが入りません

<注意>
データベースエンジンは、テーブルの主キーフィールドを予めインデックスとして保存することでレコード走査の効率を高めますが、OracleはNULL値をインデックスとして構成できないため、IS NULL演算子を使ってレコードを検索すると、すべてのレコードを読み込んで走査します。そのため、特に件数の多いテーブルでは、処理効率が著しく低下します。

こういった問題を避けるには、テーブルにレコードを追加する際、値が未定のフィールドにはあらかじめ初期値(“0”や空文字列)を設定しておくことです。SQL Serverの場合でも、わざわざテーブル全体からNULL値を持つフィールドを探す――という処理は、あまり使わない方が賢明でしょう。

但し、場合によっては意図的に初期値を設定せず、ユーザーの入力漏れをチェックする目的でIS NULLを使うこともあります。IS NULL演算子に限らずNULL値を扱う処理全般では、RDBMSのクセを把握しておきましょう。


- 文字列を指定する~LIKE -

LIKE演算子は文字列型のフィールドに対して、すべてが合致するレコード、あるいは一部だけが合致するレコードを抽出します。

書式は以下の通りです。

  <フィールド> LIKE '<文字列>'

SQLでは文字列を' 'で囲みます。<フィールド>の値が<文字列>と合致するレコードだけが抽出されるのですが、このとき<文字列>には「_(アンダースコア)」「%」などのワイルドカードが使えるため、幅広く柔軟な条件を指定できます。表2を参照してください。

LIKE演算子も、先頭に“NOT”を付けて“NOT LIKE ...”とすれば、「指定した条件以外の(指定した条件を満たさない)レコードを抽出」という意味になります。

表2:LIKE演算子で使えるワイルドカード文字
文字 機能
% 0個以上の文字で構成される任意の文字列と合致
_ 任意の1文字と合致
[ ] 指定した範囲の文字、または列挙した文字セット内の任意の1文字と合致
[^] 指定した範囲外の文字、または列挙した文字セット内に存在しない任意の1文字と合致


トップページ
値の範囲や文字列の比較を行う演算子
値の大小関係以外の比較
値の範囲を指定~BETWEEN
個別の値を指定~IN
NUUL値を見つける~IS NULL
文字列を指定する~LIKE
LIKE演算子とワイルドカード
「_」記号の特殊な用法
あとがき
Copyright © MESCIUS inc. All rights reserved.