> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL の AND、OR、および NOT

> MySQL の WHERE 句で AND、OR、および NOT を使って条件を組み合わせる方法、どれが強く結合するか、および静かに誤った行を返す 2 つの間違い。

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

1 つの条件は 1 つの質問に答えます。`AND`、`OR`、および `NOT` は条件をつなぎ、
1 つの `WHERE` で複合的な質問ができるようにします。

始める前に `mysql -u root -p sakila` でクライアントを開いてください。

## AND、OR、および NOT の仕組み

```sql theme={null}
SELECT COLUMN_LIST
FROM TABLE_NAME
WHERE FIRST_CONDITION AND SECOND_CONDITION;
```

`COLUMN_LIST` を必要な列に、`TABLE_NAME` をテーブルに、`FIRST_CONDITION` と
`SECOND_CONDITION` のそれぞれを独立したテストに置き換えます。

`AND` は両方の条件が真のときだけ行を残します。`OR` は少なくとも一方が真のとき
行を残します。`NOT` は後に続く条件を反転します。

3 つの結合の強さは同じではありません。`NOT` が最も強く、次に `AND`、その次が
`OR` です。そのためサーバーは `a OR b AND c` を `a OR (b AND c)` と読みますが、
これは書いた人の意図とはめったに一致しません。括弧はそれを上書きし、コストは
かかりません。

3 つとも比較より弱く結合します。下の `NOT rating = 'G'` が列だけではなく比較
全体を反転するのはそのためです。

## 例

### 両方の条件

```sql theme={null}
SELECT title, rating, length
FROM film
WHERE rating = 'G' AND length > 180
ORDER BY title;
```

```text theme={null}
+-----------------+--------+--------+
| title           | rating | length |
+-----------------+--------+--------+
| BAKED CLEOPATRA | G      |    182 |
| CATCH AMISTAD   | G      |    183 |
| CONTROL ANTHEM  | G      |    185 |
| DARN FORRESTER  | G      |    185 |
| INTRIGUE WORST  | G      |    181 |
| LAWLESS VISION  | G      |    181 |
| MOONWALKER FOOL | G      |    184 |
| MUSCLE BRIGHT   | G      |    185 |
| YOUNG LANGUAGE  | G      |    183 |
+-----------------+--------+--------+
9 rows in set (0.00 sec)
```

9 本の映画がレーティング `G` で、180 分を超えています。

### いずれかの条件

```sql theme={null}
SELECT title, rating
FROM film
WHERE rating = 'G' OR rating = 'PG'
ORDER BY title
LIMIT 5;
```

```text theme={null}
+------------------+--------+
| title            | rating |
+------------------+--------+
| ACADEMY DINOSAUR | PG     |
| ACE GOLDFINGER   | G      |
| AFFAIR PREJUDICE | G      |
| AFRICAN EGG      | G      |
| AGENT TRUMAN     | PG     |
+------------------+--------+
5 rows in set (0.00 sec)
```

1 つの列を値のリストと照合するのはよくあることなので、専用の演算子があります。
[IN](https://villagesql.com/docs/ja/tutorial/in.md) は同じフィルタを 1 つの句で書きます。

### 条件を反転する

```sql theme={null}
SELECT title, rating
FROM film
WHERE NOT rating = 'G'
ORDER BY title
LIMIT 5;
```

```text theme={null}
+------------------+--------+
| title            | rating |
+------------------+--------+
| ACADEMY DINOSAUR | PG     |
| ADAPTATION HOLES | NC-17  |
| AGENT TRUMAN     | PG     |
| AIRPLANE SIERRA  | PG-13  |
| AIRPORT POLLOCK  | R      |
+------------------+--------+
5 rows in set (0.00 sec)
```

`NOT rating = 'G'` と `rating <> 'G'` は同じ行を選びます。単一の比較には `<>`
を使い、`NOT` はより大きなものを反転するために取っておいてください。

## AND は OR より強く結合する

これは「レーティングが G または PG で、かつ 180 分超」のように見えます。

```sql theme={null}
SELECT title, rating, length
FROM film
WHERE rating = 'G' OR rating = 'PG' AND length > 180
ORDER BY title;
```

```text theme={null}
+---------------------------+--------+--------+
| title                     | rating | length |
+---------------------------+--------+--------+
| ACE GOLDFINGER            | G      |     48 |
| AFFAIR PREJUDICE          | G      |    117 |
| AFRICAN EGG               | G      |    130 |
...
+---------------------------+--------+--------+
182 rows in set (0.00 sec)
```

182 行あり、最初の 1 本は 48 分です。`AND` が隣の組に結合したため、サーバーは
「レーティングが G、またはレーティングが PG で 180 分超」と答えました。`G` の
映画はすべて、長さにかかわらず最初の分岐だけで条件を満たしました。

括弧が意図を伝えます。

```sql theme={null}
SELECT title, rating, length
FROM film
WHERE (rating = 'G' OR rating = 'PG') AND length > 180
ORDER BY title;
```

```text theme={null}
+-----------------+--------+--------+
| title           | rating | length |
+-----------------+--------+--------+
| BAKED CLEOPATRA | G      |    182 |
| CATCH AMISTAD   | G      |    183 |
| CONTROL ANTHEM  | G      |    185 |
| DARN FORRESTER  | G      |    185 |
| INTRIGUE WORST  | G      |    181 |
| LAWLESS VISION  | G      |    181 |
| MONSOON CAUSE   | PG     |    182 |
| MOONWALKER FOOL | G      |    184 |
| MUSCLE BRIGHT   | G      |    185 |
| RECORDS ZORRO   | PG     |    182 |
| STAR OPERATION  | PG     |    181 |
| WORST BANGER    | PG     |    185 |
| YOUNG LANGUAGE  | G      |    183 |
+-----------------+--------+--------+
13 rows in set (0.01 sec)
```

13 行です。どちらのクエリも無効ではなく、何も警告してくれないため、唯一の
防御策は、`AND` と `OR` を混ぜるたびに書きながら括弧で囲むことです。

## OR は裸の 2 つ目の値を取らない

`rating = 'G' OR 'PG'` は、英語では「レーティングが G または PG」と読めます。
サーバーにとっては 2 つの別々の条件であり、2 つ目は文字列 `'PG'` が単独で
立っているものです。

```sql theme={null}
SELECT title, rating
FROM film
WHERE rating = 'G' OR 'PG'
ORDER BY title
LIMIT 5;
```

```text theme={null}
+-------------------+--------+
| title             | rating |
+-------------------+--------+
| ACE GOLDFINGER    | G      |
| AFFAIR PREJUDICE  | G      |
| AFRICAN EGG       | G      |
| ALAMO VIDEOTAPE   | G      |
| AMISTAD MIDSUMMER | G      |
+-------------------+--------+
5 rows in set, 1 warning (0.00 sec)
```

`G` の映画だけが返り、フッターは警告を 1 件報告しています。同じセッションで
`SHOW WARNINGS` を実行すると、サーバーが理由を説明します。
`Warning 1292 Truncated incorrect DOUBLE value: 'PG'` です。

条件は真か偽でなければならないため、サーバーは `'PG'` を数値に変換しました。
`'PG'` は数字で始まらないので 0 に変換され、それは偽です。したがって 2 つ目の
分岐全体が無効でした。両側で列を指定するか、[IN](https://villagesql.com/docs/ja/tutorial/in.md) を使って
ください。

## NOT は直後のものだけを反転する

```sql theme={null}
SELECT title, rating, length
FROM film
WHERE NOT rating = 'G' AND length > 180
ORDER BY title;
```

```text theme={null}
+--------------------+--------+--------+
| title              | rating | length |
+--------------------+--------+--------+
| ANALYZE HOOSIERS   | R      |    181 |
| CHICAGO NORTH      | PG-13  |    185 |
| CONSPIRACY SPIRIT  | PG-13  |    184 |
...
+--------------------+--------+--------+
30 rows in set (0.00 sec)
```

`NOT` は隣の比較を取ったため、これは「レーティングが G ではなく、かつ 180 分超」
です。組全体を反転するには、括弧で囲みます。

```sql theme={null}
SELECT title, rating, length
FROM film
WHERE NOT (rating = 'G' AND length > 180)
ORDER BY title
LIMIT 5;
```

```text theme={null}
+------------------+--------+--------+
| title            | rating | length |
+------------------+--------+--------+
| ACADEMY DINOSAUR | PG     |     86 |
| ACE GOLDFINGER   | G      |     48 |
| ADAPTATION HOLES | NC-17  |     50 |
| AFFAIR PREJUDICE | G      |    117 |
| AFRICAN EGG      | G      |    130 |
+------------------+--------+--------+
5 rows in set (0.00 sec)
```

`ACE GOLDFINGER` はレーティング `G` で 48 分です。括弧で囲んだ組の条件を満たさ
ないため、組を反転するとこの行が残ります。

## まとめ

* すべての条件が成り立つ必要があるときは `AND` を、どれか 1 つでよいときは `OR` を使います。
* `AND` のほうが強く結合するため、`AND` と `OR` を混ぜる `WHERE` は括弧で囲みます。
* `NOT` は隣の条件だけを反転すると考えてください。
* 裸の値は数値に変換されるため、`OR` の両側で列を繰り返します。
* フッターの警告数に注意し、`SHOW WARNINGS` を実行してください。

## 関連項目

* [WHERE](https://villagesql.com/docs/ja/tutorial/where.md) — これらの演算子が組み立てる句
* [IN](https://villagesql.com/docs/ja/tutorial/in.md) — 1 つの列を複数の値と照合するより整った方法
* [演算子](https://villagesql.com/docs/ja/tutorial/operators.md) — 組み合わせられる比較


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.