SQL道場 条件マッチするレコードの検索方法
SQLでデータを検索する基本的な方法を解説。WHERE句によるデータ検索やカッコやAND演算子、OR演算子、IN演算子、BEETWEEN演算子を使ったレコードの絞込み、NOT演算子による否定検索、NULLの検索方法など記載しています。
環境
使用ツール:Microsoft SQL Server Management Studio MySQL Workbench
テーブル設計図
SQLServer

MySQL

特定の検索条件に完全一致するレコードを抽出(WHERE句)
対応:SQL Server MySQL Oracle PostgreSQL DB2 SQLite Access ANSI
基本
FROM句の後にWHERE句をつけることによって、テーブル内の特定列から条件にマッチするレコードだけを抽出することができます。WHERE句の条件式には、列、演算子、関数を使った式を記述することができます。WHERE句と比較演算子(=)を使うと条件に一致するレコードだけ抽出することができます。
SELECT * FROM テーブル名 WHERE カラム(列) = 検索条件(数字);
SELECT * FROM テーブル名 WHERE カラム(列) = '検索条件(文字、日時など)';
WHERE句以外に「INNER JOIN句」を使用することで、特定のレコードを抽出することができます。ただし、INNER JOIN句で特定のレコードを抽出する方法は、SQLパフォーマンスが悪い(検索に時間がかかる)ことがあるのでデータ量の多い(1,000万件以上)システムではなるべく使用しない方が良いでしょう。
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから性別が男だけのレコードを抜きます。SQLの実行結果は、「すなりん太郎」と「田中工事」のレコードを抜くことができます。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 性別から男性にマッチするレコードを抽出 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_SEX = '男';

MySQL
/* 性別から男性にマッチするレコードを抽出 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_SEX = '男';

NULLがあるレコードを検索(IS NULL演算子)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
NULLがセットされているレコードを抽出するには、「IS NULL」を使用します。文字列で=’NULL’ではレコードを抽出することはできません。また、NULL以外セットされているデータを検索する場合には、「IS NOT NULL」演算子を使用します。
--カラムにNULLがセットされているレコードを抽出します。
SELECT * FROM テーブル名 WHERE カラム(列) IS NULL;
--カラムにNULLがセットされていないレコードを抽出します。
SELECT * FROM テーブル名 WHERE カラム(列) IS NOT NULL;
IS NULL演算子の実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルの性別列からNULLが含まれているレコードと含まれていないレコードを抽出しています。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 | |
7 | どん 隆二 | どん りゅうじ | 3 | 25 | NULL | 1 |
SQL Server
/* 全件 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE];
/* 性別にNULLが含まれるレコードを抽出 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_SEX IS NULL;

NULLが含まれている場合は、NULLと表示されます。NULLと表示されていない場合は空がセットされています。NULLと空は異なるデータです。
MySQL
/* 全件 */
SELECT * FROM testdb.MST_EMPLOYEE;
/* 性別にNULLが含まれるレコードを抽出 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_SEX IS NULL;

IS NOT NULL演算子の実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルの性別列からNULLが含まれていないレコードと含まれていないレコードを抽出しています。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 | |
7 | どん 隆二 | どん りゅうじ | 3 | 25 | NULL | 1 |
SQL Server
/* 全件 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE];
/* 性別にNULLが含まれないレコードを抽出 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_SEX IS NOT NULL;

MySQL
/* 全件 */
SELECT * FROM testdb.MST_EMPLOYEE;
/* 性別にNULLが含まれないレコードを抽出 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_SEX IS NOT NULL;

複数の条件に完全一致するレコードを検索(AND演算子)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
基本
複数条件でデータを抽出したい場合は、WHERE句の条件に続けて「AND演算子」を使用することで、複数の条件でデータを抽出することができます。AND演算子はすべての条件が成立(true)になるレコードを抽出します。また、「AND演算子」はいくつも繋げて条件を足していくことができます。「AND演算子」と「OR演算子」の併用も可能です。
SELECT * FROM テーブル名 WHERE カラム(検索対象列) = 検索条件 AND ・・・・;
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから性別が「男」かつ年齢が「26歳」のレコードを抜きます。SQLの実行結果は、「田中工事」のレコードのみ表示されます。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 男性かつ26歳のレコードを抽出 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_SEX = '男' AND EMP_AGE = 26;

MySQL
/* 男性かつ26歳のレコードを抽出 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_SEX = '男' AND EMP_AGE = 26;

複数の条件に完全一致する条件を複数指定(OR句)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
基本
AまたBまたC・・・などのようにAにもマッチしBにもCにも・・・マッチするレコードを検索したい場合は、OR演算子を活用します。検索条件をORで繋げた場合は、AまたBとなり条件列にAかBどちらか一方及び両方がある条件にマッチするレコードを抽出します。また、OR句はいくつも繋げて条件を増やすことができます。AND演算子とOR演算子の併用も可能です。
SELECT * FROM テーブル名 WHERE カラム(検索対象列) = 検索条件 OR ・・・・;
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから性別が「男」かつ年齢が「23歳」のレコードを抜きます。SQLの実行結果は、「すなりん太郎」、「田中工事」、「佐藤じゅん」、「佐々木ゆん」のデータを抜くことができます。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 男性または23歳のレコードを抽出 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_SEX = '男' OR EMP_AGE = 23;

MySQL
/* 男性または23歳のレコードを抽出 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_SEX = '男' OR EMP_AGE = 23;

カッコを使った複数条件によるレコード検索(優先順位)
対応:SQL Server MySQL Oracle PostgreSQL DB2 SQLite Access ANSI
基本
WHERE句の後にAND演算子とOR演算子を使用して複数条件を指定することができますが、カッコ()を用いることによって検索条件をグループピング(まとめる)することもできます。カッコ内の検索条件が最初に評価され、その評価された結果をさらにAND演算子やOR演算子で評価させることができます。より、複雑な抽出条件を構築することができます。
SELECT * FROM テーブル名 WHERE (カラム=検索条件 AND カラム=検索条件) OR カラム=検索条件;
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから「男」かつ「30歳以上」、もしくは、「女」かつ「35歳以上」の条件にマッチするレコードを抽出しております。これは、まずは()内側が評価されます。その後()の外側が評価され結果を出力しています。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 男かつ30歳以上 または 女かつ35歳以上のレコードを抽出 */
SELECT
*
FROM [SampleDB].[dbo].[MST_EMPLOYEE]
WHERE (EMP_SEX = '男' AND EMP_AGE >= 30) OR (EMP_SEX = '女' AND EMP_AGE >= 35);

OR句をAND句に変えると条件にマッチするレコードは0件になります。男性かつ30歳以上で、女性かつ35歳以上という条件となりデータ上ありえないからです。
MySQL
/* 男かつ30歳以上 または 女かつ35歳以上のレコードを抽出 */
SELECT
*
FROM testdb.MST_EMPLOYEE
WHERE (EMP_SEX = '男' AND EMP_AGE >= 30) OR (EMP_SEX = '女' AND EMP_AGE >= 35);

複数の条件値にマッチするデータを抽出(IN演算子)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
基本
WHERE句に続けてIN演算子を活用することで、複数の値にマッチするレコードを抽出することができます。IN演算子内の値には、レコード内の実際の値をセットします。例えば、20歳と25歳のデータを検索したい場合は、IN(20,25)となります。OR句でも同様のことができますが、同じ列に対して複数条件を指定する点になります。OR句は、別々の列(カラム)に対して条件指定できますが、IN句は同じ列(カラム)になります。
複数IN演算子を使用する場合は、AND演算子及びOR演算子と併用します。
/*文字列・日付タイプの検索*/
SELECT * FROM テーブル名 WHERE カラム IN('値','値',・・・・);
/*数字タイプの検索*/
SELECT * FROM テーブル名 WHERE カラム IN('値','値',・・・・);
SELECT * FROM テーブル名 WHERE カラム IN('値','値',・・・・) AND カラム IN('値','値',・・・・) ;
SELECT * FROM テーブル名 WHERE カラム IN('値','値',・・・・) OR カラム IN('値','値',・・・・) ;
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルの年齢列から20歳と35歳にマッチするレコードを検索する。検索結果は、「すなりん太郎」と「博多ぴーち」のレコードが抽出される。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 20歳と35歳を検索 */
SELECT
*
FROM [SampleDB].[dbo].[MST_EMPLOYEE]
WHERE EMP_AGE IN (20,35);

MySQL
/* 20歳と35歳を検索 */
SELECT
*
FROM testdb.MST_EMPLOYEE
WHERE EMP_AGE IN (20,35)

条件マッチしないデータを抽出(NOT演算子)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
基本
WHERE句に続けてNOT演算子を使用することで条件にマッチしない(False)レコードを検索することができます。
--検索条件が文字列及び日付
SELECT * FROM テーブル名 WHERE NOT カラム = '検索条件';
--検索条件が数字
SELECT * FROM テーブル名 WHERE NOT カラム = 検索条件;
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから年齢が20歳以外のレコードを抜いています。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 20歳以外のレコードを検索 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE NOT EMP_AGE = 20;

MySQL
/* 20歳以外のレコードを検索 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE NOT EMP_AGE = 20;

データが範囲内にマッチするレコードを検索(BETWEEN演算子)
対応:SQL Server MySQL Oracle PostgreSQL DB2 Access ANSI
基本
WHERE句に続けてBETWEEN演算子を使用することで、テーブル内のデータが範囲に収まっているレコードを抽出することができます。また、NOT演算子を使用することで範囲外のレコードを抽出することもできます。
--検索条件が文字列及び日付
SELECT * FROM テーブル名 WHERE カラム BETWEEN 開始の値 AND 終了の値;
--検索条件が数字
SELECT * FROM テーブル名 WHERE カラム NOT BETWEEN 開始の値 AND 終了の値;
BETWEEN演算子を使用せずに、>=演算子と<=演算子を用いて同じことができます。
SELECT * FROM テーブル名 WHERE カラム >= 値 AND カラム <= 値;
BETWEENと「>=」「<=」演算子どうちらを使ったほうが良いか。個人的にはBETWEENをあまり使っていません。理由は以上未満が見ため誤認しやすいからです。BETWEENは指定した条件式は以上以下です。たま~に開発現場では未満などで誤認して使用しているエンジニアがいます。「>=」「<=」であれば指定した値を含む場合は=(イコール)が付いているためわかりやすいです。付いていない場合は未満となります。
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルから年齢が20歳以上29歳以下のレコードを検索しています。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 20歳以上29歳以下レコードを検索 */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] WHERE EMP_AGE BETWEEN 20 AND 29;

MySQL
/* 20歳以上29歳以下レコードを検索 */
SELECT * FROM testdb.MST_EMPLOYEE WHERE EMP_AGE BETWEEN 20 AND 29;
