📖 テーマ設定
🔊 音声設定
1.2
1.0
1.0
▶️ 再生コントロール
🎵 BGM設定
0.3
🔔 効果音設定
0.3

複合条件クエリ演習

概要

  • 日程: Day 1 / セッション 9
  • 時間: 14:55-15:40
  • 形式: 実習
  • ゴール: 「給与40万以上の営業部社員を給与降順で並べる」のような複合条件のクエリを5本書ける
  • 学習形式: ハンズオン実習(AIペアプログラミング)

導入(5分)

セッション7で「人を1つの条件で探す」、セッション8で「並べる・パターンで探す・範囲で探す」道具を覚えました。ここからはそれらを 組み合わせる 時間です。

実務でやってくるリクエストはほとんどが複合条件です。「営業部 かつ 給与40万以上の人を給与の高い順に」「Gmailアドレス 以外 の顧客」「在庫が少なくて かつ 単価が高い商品」——日本語でも「かつ」「または」「以外」が連なります。SQLの AND OR NOT がそれに対応します。

複合条件で気をつけるのは「優先順位」と「括弧」。算数の 2 + 3 × 4 で掛け算が先に来るのと同じで、SQLにも演算子の優先順位があります。今日はそこに注目して書いていきましょう。

本編(10分)

1. AND と OR の優先順位

ANDOR より先に評価されます。掛け算が足し算より優先されるのと同じ感覚です。

-- 営業部 かつ 給与40万以上、または 開発部
SELECT * FROM employees
WHERE department_id = 1 AND salary >= 400000
   OR department_id = 2;

このSQLの意味は 「(営業部 かつ 給与40万以上) または (開発部)」 です。AND のほうが先にくっつくので、開発部の人は給与にかかわらず全員出てきます。

もし意図が違うなら、括弧で囲んで優先順位を明示します。

-- 「営業部または開発部」 かつ 給与40万以上
SELECT * FROM employees
WHERE (department_id = 1 OR department_id = 2)
  AND salary >= 400000;

実務で複合条件を書くときは、自信がなくても 常に括弧をつける くらいの感覚で良いです。後から読み返すときも楽になります。

ここがポイント

  • AND > OR の優先順位(ANDが先)
  • 迷ったら括弧で明示
  • 改行とインデントで視覚的に整える

2. NOT と否定の書き方

「○○以外」を表現するときは NOT<>NOT INNOT LIKE などを使います。

-- 営業部以外の社員
SELECT * FROM employees
WHERE department_id <> 1;

-- 営業部・開発部のどちらでもない社員
SELECT * FROM employees
WHERE department_id NOT IN (1, 2);

-- メアドが gmail.com で終わらない顧客
SELECT * FROM customers
WHERE email NOT LIKE '%@gmail.com';

たとえると、検索エンジンで「除外したいキーワードに - をつける」のと似ています。「あれは欲しい、でもあれは要らない」を一発で書けるのが NOT の役割です。

ここがポイント

  • <> または != は等価でない
  • NOT IN (...) は「リストのどれにも該当しない」
  • NOT LIKE で「パターンに一致しない」

コラム

NOT を多用すると、SQLは急速に読みにくくなります。「営業部でも開発部でもなく、かつ給与が30万未満でもない人」のような条件は、書いたあなたが翌日読み返しても意味が分からなくなりがちです。プロのSQL書き職人は「肯定形で書けるならそうする」を信条にしています。たとえば「給与30万未満でない人」より「給与30万以上の人」のほうが、人間の頭にも素直に入ります。SQLは機械への命令でもありますが、半分はチームメイトへの手紙です。

💬 AIに聞いてみよう

  • ANDOR の優先順位を間違えそうで怖いです。常に括弧を書いておくのは過剰でしょうか?」
  • NOT を使った条件と、肯定で書いた条件、可読性ってどっちが上ですか?」
  • 「演算子の優先順位を全部覚える必要ありますか?括弧で済ませるのはアリですか?」

実習・演習(25分)

課題

以下の5本を順に書いてください。書き上がったらそれぞれ実行し、結果の件数と数行のサンプルをメモに残します。

Q1. 給与が40万以上の営業部社員を、給与の降順で並べる

ヒント:WHERE salary >= 400000 AND department_id = 1ORDER BY salary DESC

Q2. メールアドレスが @example.com で終わる社員のうち、給与が35万円未満の人を給与の昇順で並べる

ヒント:LIKE '%@example.com'AND salary < 350000ORDER BY salary ASC

Q3. customers テーブルから、メールアドレスが @gmail.com 以外の顧客を、顧客名の昇順で並べる

ヒント:NOT LIKE '%@gmail.com'(このsandboxにgmailは登場しないかもしれません。実行して「全件返ってくる」のが正解)

Q4. products テーブルから、電子機器(category_id = 1)またはオフィス用品(category_id = 2)のうち、価格が1万円以下の商品を、価格の昇順で並べる

ヒント:(category_id = 1 OR category_id = 2) AND price <= 10000 または category_id IN (1, 2) AND price <= 10000

Q5. employees テーブルから、入社日が 2019-01-01 〜 2021-12-31 で、給与が40万以上50万以下の社員を、入社日の昇順で並べる

ヒント:BETWEEN '2019-01-01' AND '2021-12-31'AND salary BETWEEN 400000 AND 500000

成果物

  • 5本のSQLクエリ(.sql ファイルに整理)
  • 各クエリの結果件数と、上位3行のサンプル
  • 「想定と違う結果になったQ」とその原因の分析(自分の言葉で1〜2行)

ヒント

  • まず日本語で「何と何を AND でつなぐか、何と何を OR でつなぐか」を整理してからSQLを書く
  • 括弧の位置に迷ったら 両方の書き方で実行して結果件数を比較。違いが出るところがまさに優先順位の効果
  • AI に聞くときは「このSQLを書いて」ではなく「Q4を IN で書いた版と OR で書いた版、両方見せて違いを説明して」のような問い方をすると深く学べる

まとめ(5分)

一言でまとめると「ANDOR は優先順位が違うから、迷ったら括弧。NOT は便利だけど読みにくくなりがちだから、肯定で書けるならそうする」。

今日のここまでで、employees / products / customers を 1テーブル単位 で柔軟に絞り込めるようになりました。複数テーブルを跨いだ操作(例:「営業部の社員それぞれの注文を集計する」)は明日のJOINで扱います。今日のラスト2セッションは、絞り込んだ後の 集計 —— 「数を数える、平均を出す、合計を出す」がテーマです。

🔄 振り返りチェック

  • WHERE a = 1 OR a = 2 AND b = 3 は、どの条件をどう括った意味になりますか?
  • 「営業部以外」を3通り以上の書き方で表現できますか?
  • 括弧をつけずに書いたSQLを後で読み返して、自分は2週間後にも意味を即座に把握できると思いますか?

補足資料

  • 発展課題: 自分でビジネスシーンを1つ想像し、「○○部の××以上の社員を△△順で」というクエリを1本作って実行する

学習ガイド

想定される質問と回答例

質問 ヒント
INOR の連続、どちらが速い? 多くの場面で IN のほうがDB最適化されている。可読性の意味でも IN を推奨
WHERE a = 1 AND a = 2 と書くと? 「1かつ2」は両立しないので結果0件。エラーにはならない
(salary >= 400000) AND (department_id = 1) のように両方括弧をつけても問題ない? 全く問題ない。冗長だが意図が明確になるので教育上はむしろ良い
BETWEEN>= AND <= どっちを使う? 単純な範囲なら BETWEEN のほうが短く意図が明確。境界を含めたくないときは >= AND < 等で書き分ける

つまずきやすいポイント

つまずきポイント ヒント
AND OR の優先順位を忘れる 「ANDのほうが結びつきが強い(掛け算と同じ)」と覚える。迷ったら必ず括弧
全角のスペースが混入してエラー エディタで全角空白を可視化する設定にしておく
NOT LIKE '%gmail%' で意図しない除外 部分一致は「文字列のどこかに gmail があれば除外」。先頭・末尾を意識して %@gmail.com のように書く
結果件数が0でデバッグできない 条件を1つずつ外して WHERE を弱め、どの条件が0件にしているか切り分ける
SELECT * で列が多すぎて結果が読みにくい 検索に使った列だけ SELECT に並べる、または \x で拡張表示
読み上げを開始します...

AIに質問する