【SQL】絞り込み条件:対象レコードをどのように絞り込むか(各種演算子, IN, LIKE, AND, OR, NOT)

# はじめに
SQLはデータベースを操作するためのプログラムです。
プログラムをどのように分解するかは賛否あると思いますが、
ここでは以下の４つに分類して基本の構文をまとめます。

- [処理内容:検索/更新/挿入/削除のいずれの処理をおこなうか](https://qiita.com/yatto5/items/4a2105318f6b2a8520bf)
- [対象テーブル:処理対象のテーブルと、テーブル間の関係](https://qiita.com/yatto5/items/0f64db56928c84deaca0)
- **絞り込み条件:対象レコードをどのように絞り込むか**
- 表示条件・計算など:定義された関数での計算や表示順など

このページでは絞り込み条件の基本構文をまとめます。
絞り込みの条件には「演算子」「複数指定」「曖昧検索」「条件結合」「条件否定」などがあります。
基本的にWHERE句の中で使います。

例として、[こちら](https://qiita.com/yatto5/items/4a2105318f6b2a8520bf)に掲載しているテーブルを使って、各条件の動きを解説します。

#演算子
演算子を使って条件を指定する方法です。

|演算子|意味|
|:--:|:--:|
| = | 等しい |
| <> | 等しくない |
| < | 左辺が右辺より小さい|
| > | 左辺が右辺より大きい|
| <= | 左辺が右辺以下|
| >= | 左辺が右辺以上|

```SQL:Operator
SELECT * FROM MEMBER_LIST_2ND
   WHERE STATUS_ID = '2'
```
STATUS_IDが「2」のものだけ抽出されるので、実行結果は1レコードのみです。
*2をシングルクォーテーションで囲っていますが、仮にSTATUS_IDが数値型なら囲っても囲わなくても同じ結果を得られます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0002|山田|太郎|1981/3/1|M|2||

#複数指定(IN)
演算子の"="は一致する値を1つしか指定することはできませんが、INを使うことで複数指定することができます。

```SQL:IN
SELECT * FROM MEMBER_LIST_1ST
   WHERE ID IN ('0001', '0003')
```
IDが"0001","0003"のデータを抽出することができるので、実行結果は2レコードが抽出されます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0001|鈴木|太郎|1980/10/25|M|1||
|0003|佐藤|長次郎|1980/4/2|M|1||

#曖昧検索(LIKE)
特定の語句を含むデータを検索することができます。
LIKEの十件に指定できるのは2つあり、
"%"が0文字以上の任意の文字列でいわゆるワイルドカード、
"_"は1文字の任意の文字となります。

```SQL:LIKE
SELECT * FROM MEMBER_LIST_2ND
   WHERE FIRST_NAME LIKE '%朗%'
```
この結果は名前に「朗」を含む3レコード

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0001|鈴木|太郎|1980/10/25|M|1||
|0002|山田|太郎|1981/3/1|M|2||
|0003|佐藤|長次郎|1980/4/2|M|1||

```SQL:LIKE_2
SELECT * FROM MEMBER_LIST_2ND
   WHERE FAMIRY_NAME LIKE '_朗'
```
この場合は"_"が一文字分しか表さないため、「長次郎」さんは抽出されなくなり、2レコードのみとなります。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0001|鈴木|太郎|1980/10/25|M|1||
|0002|山田|太郎|1981/3/1|M|2||

#条件結合(AND, OR)
複数の条件を検証する方法になります。

```SQL:AND
SELECT * FROM MEMBER_LIST_2ND
   WHERE GENDER= 'M'
   AND STATUS_ID = '2'
```
「GENDERがM」かつ「STATUS_IDが2」なので1レコードのみ抽出されます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0002|山田|太郎|1981/3/1|M|2||

```SQL:OR
SELECT * FROM MEMBER_LIST_2ND
   WHERE GENDER= 'F'
   OR STATUS_ID = '1'
```
「GENDERがF」または「STATUS_IDが1」なので4レコードが抽出されます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0001|鈴木|太郎|1980/10/25|M|1||
|0003|佐藤|長次郎|1980/4/2|M|1||
|0004|鈴木|定子|1980/8/2|F|1||
|0005|鈴本|花子|1980/12/14|F|1||


#条件否定(NOT)
これまで記載してきた条件を否定の意味に変えるNOT条件です。

```SQL:NOT
SELECT * FROM MEMBER_LIST_2ND
   WHERE ID NOT IN ('0001', '0004')
```
IDが"0001","0004"以外のデータになるため、3レコード抽出されます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0002|山田|太郎|1981/3/1|M|2||
|0003|佐藤|長次郎|1980/4/2|M|1||
|0005|鈴本|花子|1980/12/14|F|1||

```SQL:NOT_2
SELECT * FROM MEMBER_LIST_2ND
   WHERE STATUS_ID = '1'
   AND NOT( GENDER= 'M'
      OR FAMILY_NAME LIKE '_木')
```
「STATUSが"1"」かつ「GENDERがMまたは姓が"?木"」ではないので、1レコードのみ抽出されます。

|ID|FAMIRY_NAME|FIRST_NAME|BIRTH_DAY|GENDER|STATUS_ID|NOTE|
|---|---|---|---|---|---|---|
|0005|鈴本|花子|1980/12/14|F|1||