WHERE 句の使い方
shain社員
| name | taishoku_on |
|---|---|
| 中村 | NULL |
| 井上 | NULL |
| 山本 | 2024-03-31✕ |
| 高橋 | 2025-09-30✕ |
| … | |
WHERE絞り込んだ結果
| name | taishoku_on |
|---|---|
| 中村 | NULL |
| 井上 | NULL |
| … | |
WHERE taishoku_on IS NULL
- 取り消し線= 条件に合わないので結果に出てこない行
- 社員 18 行 → 絞り込んだ結果 16 行(2 行が消えます)
WHERE は「どの行を残すか」を決める場所です。 1 行ずつ条件に当てはめて、真になった行だけが結果に残ります。偽の行と、どちらとも言えない行は残りません。
主要 7 製品で通用 そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database / IBM Db2
このページの実行結果と図は、すべて本物のデータベースに同じ SQL を流して得たものです。手で書いた「たぶんこうなる」ではありません。
01書く場所は FROM の後ろ
結論: `SELECT … FROM 表 WHERE 条件` の順に書きます。
読む順番は書く順番と違います。まず FROM で表を決め、次に WHERE で行を絞り、最後に SELECT で列を選びます。「絞ってから列を選ぶ」と覚えてください。
条件は 1 行ずつ独立に評価されます。ある行を残すかどうかを決めるとき、他の行は一切関係ありません。
SELECT name, salaryどの列を出すか(最後に効く)FROM shainどの表を見るかWHERE salary >= 600000どの行を残すかORDER BY salary DESC並び順
SELECT name, salary
FROM shain
WHERE salary >= 600000
ORDER BY salary DESC;| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 山田 | 700000 |
| 清水 | 650000 |
| 加藤 | 610000 |
(5 行)
02比較演算子は 6 つだけ
使えるのは = <> < > <= >= の 6 つです。
「等しくない」は `<>` です。 != も多くの製品で通りますが、標準は <> なので迷ったらこちらを使ってください。
文字列も比較できます。= は完全一致で、部分一致は LIKE の役目です。日付も >= などで比較できます。
SELECT name, busho_id, hired_on
FROM shain
WHERE hired_on >= DATE '2024-01-01'
ORDER BY hired_on;| name | busho_id | hired_on |
|---|---|---|
| 小林 | 2 | 2024-04-01 |
| 松本 | 3 | 2025-04-01 |
| 木村 | 7 | 2026-04-01 |
| 渡辺 | NULL | 2026-05-01 |
| 大野 | NULL | 2026-06-01 |
(5 行)
日付は DATE 'YYYY-MM-DD' と書くのが標準です。製品によって書き方が違う部分なので、注記が出ています。
⚠️ この書き方は SQLite / SQL Server / Oracle Database では使えません(DATE 'YYYY-MM-DD' の日付リテラル)。製品ごとの対応表
03⚠️ よくある間違い:AND と OR は AND のほうが強い
AND は OR より先に評価されます。掛け算が足し算より先に計算されるのと同じです。
つまり A OR B AND C は A OR (B AND C) の意味になります。(A OR B) AND C のつもりで書くと、まったく違う行が返ります。
迷ったら括弧を書いてください。 括弧は読み手のためでもあります。余計な括弧で怒られることはありません。
SELECT name, busho_id, salary
FROM shain
WHERE busho_id = 2 OR busho_id = 3 AND salary >= 600000
ORDER BY shain_id;| name | busho_id | salary |
|---|---|---|
| 佐藤 | 2 | 720000 |
| 田中 | 2 | 520000 |
| 中村 | 2 | 530000 |
| 小林 | 2 | 445050 |
| 山田 | 3 | 700000 |
(5 行)
開発(busho_id = 2)は給与に関係なく全員出ています。書いた人の意図と違うはずです。
SELECT name, busho_id, salary
FROM shain
WHERE (busho_id = 2 OR busho_id = 3) AND salary >= 600000
ORDER BY shain_id;| name | busho_id | salary |
|---|---|---|
| 佐藤 | 2 | 720000 |
| 山田 | 3 | 700000 |
(2 行)
「開発か営業」で、かつ「60 万以上」。件数が減りました。
04⚠️ よくある間違い:NULL は「= で比べられない」
SQL の NULL は「値が無い」ではなく 「値が分からない」 という意味です。
分からないものと何かを比べても、答えは真でも偽でもなく 「どちらとも言えない(unknown)」 になります。WHERE は真になった行だけを残すので、unknown の行は落ちます。
つまり WHERE taishoku_on = NULL は何も返しません。エラーにもなりません。ここが最も事故が多い場所です。
判定したいときは `IS NULL` / `IS NOT NULL` を使います。
SELECT name, taishoku_on
FROM shain
WHERE taishoku_on = NULL;| name | taishoku_on |
|---|
(0 行)
退職日が NULL の社員は実際にはいるのに、1 行も返りません。
SELECT name, taishoku_on
FROM shain
WHERE taishoku_on IS NOT NULL
ORDER BY shain_id;| name | taishoku_on |
|---|---|
| 高橋 | 2025-09-30 |
| 山本 | 2024-03-31 |
(2 行)
退職日が入っている社員(=退職者)だけが返ります。
05⚠️ よくある間違い:NOT で否定すると、NULL の行は戻ってこない
「所属が 2 以外の社員」を出したくて WHERE busho_id <> 2 と書くと、部署が未設定(NULL)の社員が消えます。
理由は同じで、NULL <> 2 は真ではなく unknown だからです。「2 ではない」と言い切れないので残らない、と考えると腑に落ちます。
NULL も含めたいなら、明示的に足す必要があります。
SELECT name, busho_id
FROM shain
WHERE busho_id <> 2
ORDER BY shain_id;| name | busho_id |
|---|---|
| 鈴木 | 1 |
| 加藤 | 5 |
| 吉田 | 5 |
| 山田 | 3 |
| 高橋 | 3 |
| 伊藤 | 3 |
(12 行 … うち先頭 6 行を表示)
SELECT name, busho_id
FROM shain
WHERE busho_id <> 2 OR busho_id IS NULL
ORDER BY shain_id;| name | busho_id |
|---|---|
| 鈴木 | 1 |
| 加藤 | 5 |
| 吉田 | 5 |
| 山田 | 3 |
| 高橋 | 3 |
| 伊藤 | 3 |
(14 行 … うち先頭 6 行を表示)
1 行増えています。増えた行が「部署が未設定の社員」です。
06⚠️ よくある間違い:WHERE では列の別名が使えない
SELECT salary * 12 AS nenshu と付けた別名を WHERE nenshu > … と書くとエラーになります。
WHERE は SELECT より先に評価されるので、その時点ではまだ別名が存在しないためです(冒頭の解剖図の順番のとおり)。
対処は「式をそのまま書く」か、後で学ぶ副問い合わせに包むかです。まずは式をそのまま書くやり方で十分です。
SELECT name, salary * 12 AS nenshu
FROM shain
WHERE nenshu > 7000000;「そんな列は無い」と言われます。WHERE の時点では別名がまだ作られていません。
SELECT name, salary * 12 AS nenshu
FROM shain
WHERE salary * 12 > 7000000
ORDER BY salary DESC;| name | nenshu |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 山田 | 8400000 |
| 清水 | 7800000 |
| 加藤 | 7320000 |
(5 行)
自分で打ってみる
このページの例と同じデータが入った本物のデータベースを、この場(あなたのブラウザの中)で起動できます。打った SQL がサーバーへ送られることはありません。
押すと初回だけ約 9MB を読み込みます(2 回目以降はキャッシュされます)。
解いてみる
読んだだけでは書けるようになりません。実行結果で採点します。
関連するトピック
- IS NULLNULL の判定は WHERE でいちばん事故が多いところです。
- HAVING 句集計したあとに絞り込むときは WHERE ではなく HAVING を使います。
- ORDER BY 句(練習問題)絞り込んだあとの並び順を決めます。
根拠(一次情報)
- PostgreSQL 18 マニュアル: 問い合わせ — WHERE 句一次情報・確認 2026-07-28
- PostgreSQL 18 マニュアル: 比較関数と演算子(NULL と三値論理)一次情報・確認 2026-07-28
- SQLite: SELECT(WHERE clause)一次情報・確認 2026-07-28