トップ > SQL入門 > 5章
5章 検索の絞り込み

SELECTの機能 選択


今回は絞り込み検索の方法をご紹介していきます。
この機能は選択と呼ばれています。
選択は特定の行を表示させることができます。

構文は以下の通りです。

[構文] 条件に一致する行の表示
 SELECT 列名,列名…
 FROM 表名
 [ WHERE 列名 比較演算子 値 ] ;

条件を指定して特定の行だけを取得する場合は、WHERE句を使用します。
例えば、emp_idが10の人を検索したい場合は、

SELECT *
FROM employees
WHERE emp_id = 10;

名前が、watanabeの人を検索したい場合は、

SELECT *
FROM employees
WHERE first_name = 'watanabe';

となります。

WHERE句の値


ここでWHERE句で指定する値の決まり事を覚えていきましょう。

・数値データ
WHERE emp_id = 10

・文字データ
WHERE first_name = 'watanabe'

・日付データ
WHERE HIRE_DATE = '01-JAN-99'

WHERE句の検索対象に数値データを指定する場合は、特に注意点はなく、数値を指定します。
ただし、文字データや日付データを指定する場合、シングルクォーテーションで囲みます。
また文字データで指定した値は大文字小文字が区別されます。
例では、「watanabe」すべて小文字で一致する行だけが表示されます。
日付データは、データベースの日付書式の通り指定する必要があります。今回の例では、
DD-MON-RRとなります。

比較演算子


また比較演算子は=(イコール)だけでなく、その他もあるので確認していきましょう。

比較演算子一覧
= 指定した値の行を取得
=! 指定した値以外の行を取得
>= 指定した値以下の行を取得
<= 指定した値以上の行を取得
IN =と同じだが、複数の値を指定可能
IS NULL NULLの行を取得
BETWEEN 範囲指定で行を取得
LIKE 文字パターンで行を取得
NOT 指定した値以外の行を取得

では、色々な比較演算子を使用した実行例を確認していきましょう。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE emp_id != 10;

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           1 Suzuki
           2 Sato
           3 Yamamoto
           4 Watanabe
           5 Watanabe
           6 Kataoka
           7 Harada
           8 Koda
           9 Saito
          11 Sato
          12 Tao
          13 Kaneko
  …

  19 rows selected.


上記例では、WHERE句がemp_id != 10となっているので、
emp_idが10以外の行を取得します。

  SQL> SELECT first_name,salary
    2  FROM employees
    3  WHERE salary <= 6000000;

  FIRST_NAME                         SALARY
  ------------------------------ ----------
  Yamamoto                          5000000
  Watanabe                          6000000
  Watanabe                          5500000
  Sato                              5400000
  Tao                               5400000
  Kaneko                            5400000
  Totsuka                           5400000
  Kuroda                            4000000
  Nakamura                          4000000
  Kamata                            4000000
  Ito                               4000000

  11 rows selected.


上記例では、WHERE句がsalary <= 6000000となっているので、
給与が600万以下の行を取得します。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE emp_id IN (10,11);

      EMP_ID FIRST_NAME
  ---------- ------------------------------
          10 Akagi
          11 Sato


IN句は複数の値を指定することができます。値はカンマ区切りで指定しカッコも必須です。
文字データの検索の場合も同じです。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name IN ('Suzuki','Sato');

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           1 Suzuki
           2 Sato
          11 Sato


=(イコール)も複数の指定が出来そうですが、以下のようにエラーになります。
複数の値で検索を行いたい場合は、INを使用してください

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name = ('Suzuki','Sato');
  WHERE first_name = ('Suzuki','Sato')
                 *
  ERROR at line 3:
  ORA-01797: this operator must be followed by ANY or ALL


また指定した値以外を取得したい場合は、NOT演算子を使用します。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name NOT IN ('Suzuki','Sato');

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           3 Yamamoto
           4 Watanabe
           5 Watanabe
           6 Kataoka
  …


上記では、first_nameが'Suzuki','Sato'でない従業員を表示します。
続いては、IS NULL演算子です。IS NULL演算子はNULLの値を検索したい場合に使用します。
以下の例ではmanager_idがNULLである従業員を表示します。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE manager_id IS NULL;

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           1 Suzuki


manager_idがNULLでない人を検索したい場合は、NOT演算子と組合わせで実行します。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE manager_id IS NOT NULL;

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           2 Sato
           3 Yamamoto
           4 Watanabe
           5 Watanabe
           6 Kataoka
  …


NULLの検索も=(イコール)でできそうな気もしますが、取得できません。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE manager_id = NULL;

  no rows selected


エラーにはなりませんが、「no rows selected」と表示されてしまいます。
NULLの検索の場合は、IS NULL演算子を使用します。

続いてはBETWEEN演算子です。BETWEEN演算子は範囲検索が可能な演算子です。
構文は以下の通りです。

[構文] 範囲検索
 WHERE 列名 BETWEEN 最小値 AND 最大値;

例えば、年収が500万から700万の範囲にいる人を検索したい場合は、

  SQL> SELECT emp_id,first_name,salary
    2  FROM employees
    3  WHERE salary BETWEEN 5000000 AND 7000000;

        EMP_ID FIRST_NAME                         SALARY
    ---------- ------------------------------ ----------
             3 Yamamoto                          5000000
             4 Watanabe                          6000000
             5 Watanabe                          5500000
             6 Kataoka                           6500000
             7 Harada                            6200000
             8 Koda                              6400000
             9 Saito                             6700000
            10 Akagi                             6400000
            11 Sato                              5400000
            12 Tao                               5400000
            13 Kaneko                            5400000
            14 Totsuka                           5400000
            15 Kato                              6500000
            16 Sinagawa                          6500000

  14 rows selected.


ちなみに指定した値も範囲内に含まれるので、5000000以上、7000000以下の範囲となります。
また最小の最大を反対で書いてしまうと検索できないので、ご注意ください。

  SQL> SELECT emp_id,first_name,salary
    2  FROM employees
    3  WHERE salary BETWEEN 7000000 AND 5000000;

  no rows selected


上記の例は数値データの例でしたが、BETWEEN演算子に文字データ、
日付データも使用できます。

  SQL> SELECT emp_id,first_name,salary
    2  FROM employees
    3  WHERE first_name BETWEEN 'A' AND 'K';

      EMP_ID FIRST_NAME                         SALARY
  ---------- ------------------------------ ----------
           7 Harada                            6200000
          10 Akagi                             6400000
          20 Ito                               4000000


文字データの場合は最小にアルファベット順で若い文字を先に指定します。
アルファベットの場合は「A[a]」が最小「Z[z]」が最大、ひらがなの場合、
「あ」が最小で「ん」が最大となります。
また値を大文字A,Kにしているのは、FIRST_NAME列の最初の文字が大文字だからです。
文字は大文字小文字が区別されるので、小文字で指定した場合は、違う実行結果となります。

  SQL> SELECT emp_id,first_name,salary
    2  FROM employees
    3  WHERE first_name BETWEEN 'a' AND 'k';

  no rows selected


次は日付文字を使用した実行例です。使い方は同じです。最初の値は検索したい最小の日付となります。

  SQL> SELECT emp_id,first_name,hire_date
    2  FROM employees
    3  WHERE hire_date BETWEEN '01-JAN-00' AND '01-JAN-10';

      EMP_ID FIRST_NAME                     HIRE_DATE
  ---------- ------------------------------ ---------
           6 Kataoka                        01-OCT-00
           7 Harada                         01-OCT-00
           8 Koda                           01-OCT-00
           9 Saito                          01-OCT-00
          10 Akagi                          01-MAR-01
          12 Tao                            28-JUL-03
          13 Kaneko                         22-FEB-01
          14 Totsuka                        29-SEP-03
          15 Kato                           01-APR-09
          16 Sinagawa                       01-APR-09

  10 rows selected.


日付はDD-MON-RRでしたね。DDは日付、MONは英語月の先頭3文字、RRは西暦の下2桁です。
今回の例では、2000/1/1から2010/1/1の間に入社した従業員を表示しています。

またBETWEEN演算子もNOT演算子と組み合わせることが可能です。

  SQL> SELECT emp_id,first_name,salary
    2  FROM employees
    3  WHERE salary NOT BETWEEN 5000000 AND 7000000;

      EMP_ID FIRST_NAME                         SALARY
  ---------- ------------------------------ ----------
           1 Suzuki                           10000000
           2 Sato                              8000000
          17 Kuroda                            4000000
          18 Nakamura                          4000000
          19 Kamata                            4000000
          20 Ito                               4000000

  6 rows selected.


では、最後にLIKE演算子について学んでいきましょう。
LIKE演算子はパターン検索、あいまい検索が行える演算子です。
例えば、先頭にSがつく従業員であったり、最後にaがつく従業員などの検索が可能です。

[構文] あいまい検索
WHERE 列名 LIKE '文字パターン'

文字パターンにはワイルドカードが使用できます。
ワイルドカードとは任意の文字を表すキーワードです。

ワイルドカード
 _(アンダースコア):任意の1文字を表す
 %(パーセント) :任意の文字列を表す

先頭に大文字のAがつく人を検索したい場合

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name LIKE 'A%';

      EMP_ID FIRST_NAME
  ---------- ------------------------------
          10 Akagi


最後に小文字のaがつく人を検索したい場合

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name LIKE '%a';

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           6 Kataoka
           7 Harada
           8 Koda
          14 Totsuka
          16 Sinagawa
          17 Kuroda
          18 Nakamura
          19 Kamata

  8 rows selected.


名前に小文字のuが含まれる人を検索したい場合

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name LIKE '%u%';

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           1 Suzuki
          14 Totsuka
          17 Kuroda
          18 Nakamura


2文字目にuが来る人を検索したい場合

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name LIKE '_u%';

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           1 Suzuki
          17 Kuroda


2文字目にuが来ない人を検索したい場合はNOT演算子を使用します。

  SQL> SELECT emp_id,first_name
    2  FROM employees
    3  WHERE first_name NOT LIKE '_u%';

      EMP_ID FIRST_NAME
  ---------- ------------------------------
           2 Sato
           3 Yamamoto
           4 Watanabe
           5 Watanabe
  …


ちなみにLIKE演算子は数値データは使用できません。日付データは使用可能です。
例えば、2000年入社の人を検索したい場合は、BETWEEN演算子でも検索できますが、
LIKE演算子でも使用可能です。

  SQL> SELECT emp_id,first_name,hire_date
    2  FROM employees
    3  WHERE hire_date LIKE '%00';

      EMP_ID FIRST_NAME                     HIRE_DATE
  ---------- ------------------------------ ---------
           6 Kataoka                        01-OCT-00
           7 Harada                         01-OCT-00
           8 Koda                           01-OCT-00
           9 Saito                          01-OCT-00


これではおなかいっぱいだとは思いますが、最後に1つLIKE検索での応用があります。

先ほどは文字パターンの部分にワイルドカード(%,_)を使用できると覚えてきましたが、
例えば、文字列に%が含まれる場合、どのように検索するのでしょうか。

WHERE first_name LIKE 'TOM%';

上記の場合は、%がワイルドカードと認識され、
先頭にTOMがつく人を検索してしまい、

TOM%という文字列を検索することができません。
つまり文字パターンに%,_を使用すると必ずワイルドカードとして機能してしまいます。

文字パターン内に%や_を通常の文字として使用したい場合、
ワイルドカード機能の打消しを行います。

[構文] ワイルドカードの打消し
WHERE first_name LIKE 'TOM$%' ESCAPE '$';

ESCAPEキーワードで指定した$をワイルドカードの%の前に記載することにより、
%は通常の文字として扱われるようになります。
このようにして、ワイルドカードの機能を打消しすることができます。

いかかでしたでしょうか。WHERE句を使用した絞り込みの検索を学んでいきましたが、
段々と色々なデータ取得ができるようになってきました。

理解が難しい部分は、実際にSQLを実行して確認してみてください。