> ## 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 の WHERE

> MySQL の WHERE 句が欲しい行だけを保持する仕組み、条件がテストできる列、および同じクエリの列エイリアスが見えない理由。

> [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 →

`WHERE` は条件を満たす行を保持し、残りを捨てます。これまでのすべてのレッスンは
テーブル全体を返しました。これが、テーブルを答えに変える句です。

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

## WHERE の仕組み

```sql theme={null}
SELECT COLUMN_LIST
FROM TABLE_NAME
WHERE SEARCH_CONDITION;
```

`COLUMN_LIST` を欲しい列に、`TABLE_NAME` をテーブルに、`SEARCH_CONDITION` を
サーバーが一度に 1 行ずつ適用できるテストに置き換えます。サーバーは各行を
読み、その行の値に対して条件を評価し、結果が真のときに行を保持します。偽に
なる行、または NULL になる行は捨てられます。

`WHERE` は `FROM` の後、`ORDER BY` の前に置き、それが結果が定義される順序
です。絞り込み、次に残ったものの並べ替え、次に `LIMIT` の適用です。そのため、
`WHERE` の後の `LIMIT 5` は、一致する行のうちの 5 行を返すのであって、一部が
一致する 5 行を返すのではありません。サーバーはその答えにどんな方法でたどり
着いてもよく、`EXPLAIN` がどの方法を選んだかを示します。

## 例

### 1 つの値に一致させる

Sakila はすべての映画にレーティングを付けています。これはレーティングが `G` の
映画を保持します。

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

```text theme={null}
+---------+-------------------+--------+
| film_id | title             | rating |
+---------+-------------------+--------+
|       2 | ACE GOLDFINGER    | G      |
|       4 | AFFAIR PREJUDICE  | G      |
|       5 | AFRICAN EGG       | G      |
|      11 | ALAMO VIDEOTAPE   | G      |
|      22 | AMISTAD MIDSUMMER | G      |
+---------+-------------------+--------+
5 rows in set (0.00 sec)
```

文字列は単一引用符で囲みます。数値は囲みません。

### 数値を比較する

```sql theme={null}
SELECT title, length
FROM film
WHERE length > 180
ORDER BY length DESC, title
LIMIT 5;
```

```text theme={null}
+----------------+--------+
| title          | length |
+----------------+--------+
| CHICAGO NORTH  |    185 |
| CONTROL ANTHEM |    185 |
| DARN FORRESTER |    185 |
| GANGS PRIDE    |    185 |
| HOME PITY      |    185 |
+----------------+--------+
5 rows in set (0.00 sec)
```

185 分はカタログ内で最も長い映画で、その長さの映画が 10 本あるため、最初の
5 行はすべて同点です。`title` でも並べ替えることで同点が解消され、そのおかげで
毎回同じ 5 本が返ってきます。

### 選択していない列で絞り込む

条件は結果ではなく行をテストします。ここで `rental_rate` は出力にまったく
現れませんが、フィルタは動作します。

```sql theme={null}
SELECT title
FROM film
WHERE rental_rate = 4.99
ORDER BY title
LIMIT 5;
```

```text theme={null}
+------------------+
| title            |
+------------------+
| ACE GOLDFINGER   |
| AIRPLANE SIERRA  |
| AIRPORT POLLOCK  |
| ALADDIN CALENDAR |
| ALI FOREVER      |
+------------------+
5 rows in set (0.00 sec)
```

### 1 つの値を除くすべて

```sql theme={null}
SELECT title, rating
FROM film
WHERE 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)
```

`<>` は「等しくない」です。`!=` も同じ意味で、どちらでもかまいません。

## WHERE は列エイリアスを見られない

エイリアスは結果の列に名前を付けます。`WHERE` は結果が存在する前に実行される
ため、そこでエイリアスを指定すると失敗します。

```sql theme={null}
SELECT title, rental_rate * 2 AS double_rate
FROM film
WHERE double_rate > 8
ORDER BY title;
```

```text theme={null}
ERROR 1054 (42S22): Unknown column 'double_rate' in 'where clause'
```

代わりに、条件の中で式をもう一度書きます。

```sql theme={null}
SELECT title, rental_rate * 2 AS double_rate
FROM film
WHERE rental_rate * 2 > 8
ORDER BY title
LIMIT 5;
```

```text theme={null}
+------------------+-------------+
| title            | double_rate |
+------------------+-------------+
| ACE GOLDFINGER   |        9.98 |
| AIRPLANE SIERRA  |        9.98 |
| AIRPORT POLLOCK  |        9.98 |
| ALADDIN CALENDAR |        9.98 |
| ALI FOREVER      |        9.98 |
+------------------+-------------+
5 rows in set (0.00 sec)
```

`ORDER BY` はエイリアスを使える句です。結果が構築された後に実行されるため
です。[ORDER BY](https://villagesql.com/docs/ja/tutorial/order-by.md) のレッスンがそれを示しています。

## 一致なしはエラーではない

```sql theme={null}
SELECT title FROM film WHERE rating = 'X';
```

```text theme={null}
Empty set (0.00 sec)
```

`Empty set` は、クエリが実行され、条件を満たす行がなかったという意味です。
サーバーは表の代わりにこれを表示するため、列の見出しもありません。これは
1 つの答えです。

## まとめ

* 条件を満たす行だけを保持するには `WHERE` を使います。
* 文字列は単一引用符で囲み、数値はそのまま書きます。
* サーバーはまず絞り込み、次に並べ替え、次に `LIMIT` を適用すると考えてください。
* 選択したかどうかにかかわらず、テーブルのどの列でもテストできます。
* `WHERE` ではエイリアスを指定するのではなく式を繰り返します。エイリアスを指定すると `ERROR 1054` になります。

## 関連項目

* [SELECT](https://villagesql.com/docs/ja/tutorial/select.md) — WHERE が付く文
* [演算子](https://villagesql.com/docs/ja/tutorial/operators.md) — 条件を組み立てる比較
* [AND、OR、および NOT](https://villagesql.com/docs/ja/tutorial/and-or-not.md) — 複数の条件の組み合わせ
* [ORDER BY](https://villagesql.com/docs/ja/tutorial/order-by.md) — フィルタを通過したものの並べ替え


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