【初心者向け】SQLで複数条件を指定する方法|AND・OR・NOTの使い方と実践例

データベース・SQL

「年齢が20歳以上で、女性だけを表示したい」
「キャンペーン中または割引中の商品を検索したい」

──そんな要望を実現するために必要なのが、SQLの複数条件指定です。

SQLでは、WHERE句の中にAND(かつ)・OR(または)・NOT(ではない)といった論理演算子を組み合わせることで、複雑な条件も簡単に表現できます。

この記事では、SQLで複数条件を指定する方法を初心者にもわかりやすく解説し、実際の仕事でよく使う例も詳しく紹介します。

スポンサーリンク

複数条件を使うための基本

論理演算子とは?

論理演算子は、複数の条件を組み合わせるときに使う言葉です。

日常会話でも「AかつB」「AまたはB」「Aではない」という表現を使いますが、SQLでも同じように考えられます。

基本的な構文

SELECT * FROM テーブル名
WHERE 条件1 AND 条件2;

3つの論理演算子

演算子意味日常の言葉
ANDかつ、そして「〜で、なおかつ〜」age >= 20 AND gender = '女性'
ORまたは「〜か、または〜」status = '完了' OR status = '処理中'
NOTではない「〜以外」NOT status = 'キャンセル'

具体例で理解しよう

1つの条件だけの場合

SELECT * FROM users WHERE age >= 20;

→ 20歳以上の人だけ

2つの条件をANDで組み合わせた場合

SELECT * FROM users WHERE age >= 20 AND gender = '女性';

→ 20歳以上で、かつ女性の人だけ

2つの条件をORで組み合わせた場合

SELECT * FROM users WHERE age >= 60 OR age <= 18;

→ 60歳以上または18歳以下の人

ANDの使い方:「かつ」の条件

ANDは「すべての条件を満たす」ときに使います。

基本的な使い方

-- 年齢が20歳以上で、かつ東京都に住んでいる人
SELECT * FROM users 
WHERE age >= 20 AND address LIKE '%東京都%';

-- 価格が1000円以上で、かつ在庫が10個以上の商品
SELECT * FROM products 
WHERE price >= 1000 AND stock >= 10;

3つ以上の条件を組み合わせる

-- 年齢が20歳以上で、女性で、東京都に住んでいる人
SELECT * FROM users 
WHERE age >= 20 
  AND gender = '女性' 
  AND address LIKE '%東京都%';

-- 価格が500円以上1500円以下で、在庫があり、評価が4以上の商品
SELECT * FROM products 
WHERE price >= 500 
  AND price <= 1500 
  AND stock > 0 
  AND rating >= 4;

実際の業務での使用例

顧客管理システム

-- アクティブな優良顧客を検索
-- (最終ログインが30日以内で、購入金額が10万円以上)
SELECT customer_name, last_login, total_purchase
FROM customers 
WHERE last_login >= '2025-05-04'  -- 30日前
  AND total_purchase >= 100000;

在庫管理システム

-- 補充が必要な人気商品を検索
-- (在庫が20個以下で、月間売上が100個以上)
SELECT product_name, stock, monthly_sales
FROM products 
WHERE stock <= 20 
  AND monthly_sales >= 100;

ORの使い方:「または」の条件

ORは「どれかの条件を満たす」ときに使います。

基本的な使い方

-- 東京都または大阪府に住んでいる人
SELECT * FROM customers 
WHERE prefecture = '東京都' OR prefecture = '大阪府';

-- ステータスが「完了」または「発送済み」の注文
SELECT * FROM orders 
WHERE status = '完了' OR status = '発送済み';

複数の値から選択する

-- カテゴリが「本」「雑誌」「新聞」のいずれかの商品
SELECT * FROM products 
WHERE category = '本' 
   OR category = '雑誌' 
   OR category = '新聞';

-- 年齢が18歳、20歳、25歳のいずれかの人
SELECT * FROM users 
WHERE age = 18 OR age = 20 OR age = 25;

より簡潔な書き方:IN句

ORで同じ列の複数の値を指定する場合、IN句を使うとより簡潔に書けます。

-- ORを使った書き方
SELECT * FROM products 
WHERE category = '本' OR category = '雑誌' OR category = '新聞';

-- IN句を使った書き方(同じ意味)
SELECT * FROM products 
WHERE category IN ('本', '雑誌', '新聞');

実際の業務での使用例

セール対象商品の検索

-- 割引対象商品を検索
-- (在庫処分商品または季節商品)
SELECT product_name, category, stock
FROM products 
WHERE category = '在庫処分' 
   OR category = '季節限定';

緊急対応が必要なタスク

-- 優先度の高いタスクを検索
-- (優先度が「高」または「緊急」)
SELECT task_name, priority, deadline
FROM tasks 
WHERE priority = '高' OR priority = '緊急'
ORDER BY deadline;

NOTの使い方:「ではない」の条件

NOTは条件を否定するときに使います。

基本的な使い方

-- ステータスが「キャンセル」ではない注文
SELECT * FROM orders WHERE NOT status = 'キャンセル';

-- 価格が0円ではない商品
SELECT * FROM products WHERE NOT price = 0;

別の書き方

NOTは他の演算子と組み合わせて、より自然に書くこともできます。

-- NOT = の代わりに <> や != を使う
SELECT * FROM orders WHERE status <> 'キャンセル';
SELECT * FROM orders WHERE status != 'キャンセル';

-- NOT IN を使う
SELECT * FROM products 
WHERE category NOT IN ('廃盤', '販売停止');

NULLの扱い

-- メールアドレスが登録されている顧客
SELECT * FROM customers WHERE email IS NOT NULL;

-- 退職していない社員(退職日が未入力)
SELECT * FROM employees WHERE resignation_date IS NULL;

実際の業務での使用例

アクティブユーザーの分析

-- 退会していないユーザーを検索
SELECT user_name, registration_date, last_login
FROM users 
WHERE NOT status = '退会済み'
ORDER BY last_login DESC;

正常な商品の在庫確認

-- 問題のない商品を検索
-- (廃盤でも販売停止でもない商品)
SELECT product_name, stock, price
FROM products 
WHERE status NOT IN ('廃盤', '販売停止', '在庫切れ');

括弧を使った条件のグループ化

複数の論理演算子を組み合わせるときは、括弧を使って優先順位を明確にしましょう。

なぜ括弧が必要?

SQLでは、ANDがORよりも優先的に処理されます。意図しない結果を避けるために、括弧で条件をグループ化することが重要です。

問題のある例

-- この書き方だと意図しない結果になる可能性がある
SELECT * FROM orders 
WHERE status = '完了' OR status = '発送済み' AND date >= '2025-01-01';

上記の条件は、次のように解釈されます:

  • status = '完了'(いつでも)
  • または status = '発送済み' AND date >= '2025-01-01'(2025年以降の発送済み)

正しい書き方

-- 括弧を使って意図を明確にする
SELECT * FROM orders 
WHERE (status = '完了' OR status = '発送済み') AND date >= '2025-01-01';

この場合は、次のように解釈されます:

  • status = '完了' OR status = '発送済み'(完了または発送済み)
  • かつ date >= '2025-01-01'(2025年以降)

実践的な例

優良顧客の検索

-- 購入金額が高いか、購入回数が多い顧客で、かつアクティブな人
SELECT customer_name, total_amount, purchase_count, last_login
FROM customers 
WHERE (total_amount >= 100000 OR purchase_count >= 50) 
  AND last_login >= '2025-05-01';

セール対象商品の検索

-- 在庫が少ないか売れ行きが悪い商品で、かつ廃盤予定でないもの
SELECT product_name, stock, monthly_sales, status
FROM products 
WHERE (stock <= 10 OR monthly_sales <= 5) 
  AND status != '廃盤予定';

緊急対応タスクの検索

-- 締切が近いか優先度が高いタスクで、かつ未完了のもの
SELECT task_name, deadline, priority, status
FROM tasks 
WHERE (deadline <= '2025-06-10' OR priority = '緊急') 
  AND status != '完了';

実際の仕事でよく使う複数条件の例

ECサイトの商品検索

-- セール商品の検索
-- (割引率が20%以上で、在庫があり、評価が3.5以上)
SELECT product_name, price, discount_rate, stock, rating
FROM products 
WHERE discount_rate >= 20 
  AND stock > 0 
  AND rating >= 3.5
ORDER BY discount_rate DESC;

-- 人気カテゴリの新商品
-- (カテゴリが「家電」「本」「衣類」で、登録から30日以内)
SELECT product_name, category, registration_date
FROM products 
WHERE category IN ('家電', '本', '衣類') 
  AND registration_date >= '2025-05-04'  -- 30日前
ORDER BY registration_date DESC;

顧客管理システム

-- 重要顧客の検索
-- (購入金額が50万円以上か購入回数が100回以上で、かつ最近アクティブ)
SELECT customer_name, total_purchase, purchase_count, last_order_date
FROM customers 
WHERE (total_purchase >= 500000 OR purchase_count >= 100) 
  AND last_order_date >= '2025-04-01'
ORDER BY total_purchase DESC;

-- フォローが必要な顧客
-- (最終購入から6ヶ月以上経過しているが、退会はしていない)
SELECT customer_name, last_order_date, status
FROM customers 
WHERE last_order_date < '2024-12-03'  -- 6ヶ月前
  AND status != '退会済み'
ORDER BY last_order_date;

売上分析

-- 好調な売上データ
-- (今年の売上で、10万円以上か前年比150%以上)
SELECT order_date, total_amount, growth_rate
FROM daily_sales 
WHERE order_date >= '2025-01-01' 
  AND (total_amount >= 100000 OR growth_rate >= 1.5)
ORDER BY order_date DESC;

人事管理システム

-- 昇進候補者の検索
-- (勤続年数が3年以上で、評価がAまたはB+で、現在在籍中)
SELECT employee_name, years_of_service, evaluation, department
FROM employees 
WHERE years_of_service >= 3 
  AND evaluation IN ('A', 'B+') 
  AND resignation_date IS NULL
ORDER BY years_of_service DESC;

よくある間違いと対策

括弧の省略による意図しない結果

問題のあるSQL

-- 意図:「完了または発送済み」で「2025年以降」の注文
-- 実際:「完了」(いつでも)または「発送済みで2025年以降」
SELECT * FROM orders 
WHERE status = '完了' OR status = '発送済み' AND order_date >= '2025-01-01';

正しいSQL

SELECT * FROM orders 
WHERE (status = '完了' OR status = '発送済み') 
  AND order_date >= '2025-01-01';

NULLの扱い間違い

間違った例

-- NULLに対して = や != は正しく動作しない
SELECT * FROM customers WHERE email != NULL;  -- 間違い

正しい例

-- IS NOT NULL を使う
SELECT * FROM customers WHERE email IS NOT NULL;

-- NULLも含めた条件
SELECT * FROM customers 
WHERE email IS NOT NULL OR phone IS NOT NULL;

データ型の混同

問題のある例

-- 文字列として格納された数値の比較
SELECT * FROM products WHERE price_text > '100';  -- '100' > '2' になる場合がある

正しい例

-- 数値型に変換してから比較
SELECT * FROM products WHERE CAST(price_text AS INTEGER) > 100;

-- または、最初から数値型で保存する
SELECT * FROM products WHERE price > 100;

複雑すぎる条件

読みにくい例

SELECT * FROM orders 
WHERE status = 'A' OR status = 'B' AND amount > 1000 OR status = 'C' AND amount > 2000 AND date > '2025-01-01';

読みやすい例

SELECT * FROM orders 
WHERE status = 'A' 
   OR (status = 'B' AND amount > 1000) 
   OR (status = 'C' AND amount > 2000 AND date > '2025-01-01');

パフォーマンスを考えた複数条件の書き方

インデックスを活用できる順番

-- インデックスがある列を最初に書く
SELECT * FROM orders 
WHERE customer_id = 123     -- インデックスあり(高速)
  AND order_date >= '2025-01-01'  -- インデックスあり(高速)
  AND total_amount > 10000;       -- インデックスなし(低速)

OR条件でのパフォーマンス

-- ORが多い場合は、UNIONを検討する場合もある

-- OR を使った書き方
SELECT * FROM products 
WHERE category = 'A' OR category = 'B' OR category = 'C';

-- UNION を使った書き方(場合によっては高速)
SELECT * FROM products WHERE category = 'A'
UNION
SELECT * FROM products WHERE category = 'B'
UNION
SELECT * FROM products WHERE category = 'C';

-- ただし、通常はINの方が簡潔で十分
SELECT * FROM products WHERE category IN ('A', 'B', 'C');

効率的な条件の組み合わせ

-- 悪い例:全件検索してから絞り込み
SELECT * FROM large_table 
WHERE expensive_function(column1) = 'value'
  AND simple_column = 'simple_value';

-- 良い例:簡単な条件で先に絞り込み
SELECT * FROM large_table 
WHERE simple_column = 'simple_value'  -- 先に絞り込み
  AND expensive_function(column1) = 'value';

応用テクニック

範囲検索との組み合わせ

-- 年齢層別の顧客分析
SELECT customer_name, age, total_purchase
FROM customers 
WHERE (age BETWEEN 20 AND 29 OR age BETWEEN 50 AND 59) 
  AND total_purchase > 50000;

-- 期間限定キャンペーンの対象商品
SELECT product_name, price, campaign_start, campaign_end
FROM products 
WHERE campaign_start <= '2025-06-03' 
  AND campaign_end >= '2025-06-03' 
  AND (price BETWEEN 1000 AND 5000 OR discount_rate >= 30);

サブクエリとの組み合わせ

-- 平均以上の売上で、かつ特定カテゴリの商品
SELECT product_name, sales_amount, category
FROM products 
WHERE sales_amount > (SELECT AVG(sales_amount) FROM products) 
  AND category IN ('家電', '家具')
  AND stock > 0;

CASE文との組み合わせ

-- 条件に応じた分類
SELECT 
  customer_name,
  total_purchase,
  CASE 
    WHEN total_purchase >= 100000 AND purchase_count >= 50 THEN 'VIP'
    WHEN total_purchase >= 50000 OR purchase_count >= 20 THEN 'ゴールド'
    ELSE 'レギュラー'
  END as customer_rank
FROM customers 
WHERE status = 'アクティブ';

まとめ

複数条件を使えば、SQLの表現力は格段に広がります。

AND・OR・NOTを使い分けて、現実の要件を正確に反映したデータ抽出が可能になります

重要なポイント

  • AND:すべての条件を満たす(「かつ」)
  • OR:どれかの条件を満たす(「または」)
  • NOT:条件を否定する(「ではない」)
  • 括弧:複雑な条件では必ず使って優先順位を明確にする
  • NULLIS NULLIS NOT NULLを正しく使う

書き方のコツ

  • 複雑な条件は括弧でグループ化する
  • 読みやすいように改行とインデントを使う
  • インデックスがある列を優先的に条件に含める
  • 同じ列の複数値チェックにはINを使う

コメント

タイトルとURLをコピーしました