SQL CASE式による条件分岐ロジック

SELECT、WHERE、ORDER BY、集約でのSQL CASE式を使った条件分岐ロジックを学びます。SQLクエリ内でif-then-elseロジックを直接実装する方法を解説します。

Query

詳細な説明

SQL CASE式による条件分岐ロジック

CASE 式はSQLクエリ内でif-then-elseロジックを提供します。SELECT、WHERE、ORDER BY、GROUP BY、HAVING句で使用でき、SQLの最も汎用的な構文の1つです。

単純CASE

単一の式を複数の値と比較します:

SELECT name, status,
  CASE status
    WHEN 'A' THEN 'Active'
    WHEN 'I' THEN 'Inactive'
    WHEN 'P' THEN 'Pending'
    ELSE 'Unknown'
  END AS status_label
FROM users;

検索CASE

複数の独立した条件を評価します:

SELECT name, salary,
  CASE
    WHEN salary >= 120000 THEN 'Senior'
    WHEN salary >= 80000 THEN 'Mid-Level'
    WHEN salary >= 50000 THEN 'Junior'
    ELSE 'Entry Level'
  END AS salary_band
FROM employees;

条件は上から順に評価され、最初に一致したものが適用されます。

ORDER BYでのCASE

SELECT * FROM tickets
ORDER BY
  CASE priority
    WHEN 'critical' THEN 1
    WHEN 'high' THEN 2
    WHEN 'medium' THEN 3
    WHEN 'low' THEN 4
    ELSE 5
  END ASC;

集約でのCASE(ピボットクエリ)

SELECT
  department,
  COUNT(CASE WHEN gender = 'M' THEN 1 END) AS male_count,
  COUNT(CASE WHEN gender = 'F' THEN 1 END) AS female_count,
  COUNT(CASE WHEN gender NOT IN ('M', 'F') THEN 1 END) AS other_count
FROM employees
GROUP BY department;

これにより、データベース固有のPIVOT構文を使わずに行データを列にピボットできます。

CASEとNULL

SELECT name,
  CASE WHEN phone IS NULL THEN 'No phone' ELSE phone END AS phone_display
FROM contacts;
-- 以下と同等: COALESCE(phone, 'No phone')

ベストプラクティス

  • 予期しない値を処理するために常に ELSE 句を含める(省略するとデフォルトでNULLを返す)
  • CASE式は読みやすく保つ。非常に複雑なロジックはビューや計算カラムに抽出する
  • 単純なNULL処理にはCASEの代わりにCOALESCEやNULLIFを使用する
  • CASEは式(値を返す)であり、制御フロー文ではない
  • WHEREでのCASE使用はインデックスの使用を妨げることがある。可能であれば複数のOR条件に書き換える

CASE式は、クエリ内で直接強力なデータ変換と条件分岐ロジックを可能にし、アプリケーションコードでの後処理の必要性を削減します。

ユースケース

レポーティングシステムが、注文を売上ティアに分類し、CASE式を集約関数内で使用してステータスと地域ごとの注文数のクロス集計を作成する場面。

Try It — SQL Formatter

フルツールを開く