SQL CASE 式

SQL の CASE 式を使うと、条件によって返す値を分岐させることができる。データベースの種類に依存しない方法で、OracleMySQLPostgreSQLおよびSQLServerで使用できる。

CASE
DBMS CASE
MySQL
Oracle
PostgreSQL
SQL Server

使い方

CASE expr
  WHEN comp THEN return
  [WHEN comp THEN return ...]
  [ELSE return]
END
expr
評価する式
comp
比較する値
return
戻す値

CASE式を使ったSELECT文の例を次に示す。

SELECT
  CASE emp.gender
    WHEN 'M' THEN '男'
    WHEN 'W' THEN '女'
    ELSE NULL
  END
FROM emp

複数条件

SQLのCASE式では、複数の条件によって分岐することもできる。

CASE
  WHEN cond THEN return
  [WHEN cond THEN return ...]
  [ELSE return]
END
cond
条件式
return
戻す値

複数条件によって分岐するCASE式の例を次に示す。

SELECT
  CASE
    WHEN prefectures = '01' THEN '北海道'
    WHEN prefectures IN ('02', '03', '04', '05', '06', '07') THEN '東北'
    ELSE NULL
  END
FROM dept

複数カラム

CASE式で複数カラムによる条件を指定することもできる。

SELECT CASE
  WHEN job = 'salesman' AND comm IS NOT NULL THEN sal + comm
  ELSE sal
END
FROM emp;

NULL判定

NULLかどうかを判定するには、IS を使う。

歩合給(comm)がNULLであれば給料(sal)、NULLでなければ給料と歩合給の合計値を問い合わせるSQL文の例を次に示す。

SELECT
  CASE
    WHEN comm IS NULL THEN sal
    WHEN comm IS NOT NULL THEN sal + comm
  END
FROM emp

ELSEの省略

CASE式のELSE句を省略すると、「ELSE NULL」と同じ扱いになる。

入れ子

SQLのCASE式は入れ子にすることができる。階層の深さに制限は無い。

SELECT
  CASE col1
    WHEN 1 THEN
      CASE col2
        WHEN 'A' THEN 'OK'
        WHEN 'B' THEN 'NG'
      END
    ELSE 'NG'
  END
FROM emp

AS句で別名を付ける

CASE式にはAS句で別名を付けることができる。

SELECT CASE
  WHEN month IN ('03', '04', '05') THEN 'spring'
  WHEN month IN ('06', '07', '08') THEN 'summer'
  WHEN month IN ('09', '10', '11') THEN 'fall'
  WHEN month IN ('12', '01', '02') THEN 'winter'
END AS season
FROM example;

SELECT文のWHERE句でCASE式を使う

SELECT文のWHERE句でCASE式を使うこともできる。

歩合給(comm)がNULLであれば給料(sal)、NULLでなければ給料と歩合給の合計値が、5000以上のレコードを問い合わせるSQL文の例を次に示す。

SELECT * FROM emp WHERE CASE
  WHEN comm IS NULL THEN sal
  WHEN comm IS NOT NULL THEN sal + comm
END >= 5000;

UPDATE文のSET句でCASE式を使う

職種(job)ごとに給料(sal)を更新するSQL文の例を次に示す。

UPDATE emp SET sal = 9000 WHERE job = 'president';
UPDATE emp SET sal = 5000 WHERE job = 'manager';
UPDATE emp SET sal = 7000 WHERE job = 'analyst';
UPDATE emp SET sal = 3000 WHERE job NOT IN ('president', 'manager', 'analyst');

UPDATE文のSET句でCASE式を使えば、これらのSQL文をひとつに纏めることができる。

UPDATE emp SET sal = CASE job
  WHEN 'president' THEN 9000
  WHEN 'manager' THEN 5000
  WHEN 'analyst' THEN 7000
  ELSE 3000
END;

特定の職種のみ更新したければ、SQL文を次のようにする。

UPDATE emp SET sal = CASE job
  WHEN 'president' THEN 9000
  WHEN 'manager' THEN 5000
  WHEN 'analyst' THEN 7000
END
WHERE job IN ('president', 'manager', 'analyst');

関連SQL

参考文献

Microsoft 2023. CASE (Transact-SQL). SQL Server 技術ドキュメント

Oracle 2023. CASE式. Oracle® Database SQL言語リファレンス 11gリリース2 (11.2)

Oracle 2023. 13.6.5.1 CASE ステートメント. MySQL 8.0 リファレンスマニュアル

The PostgreSQL Global Development Group 2022. 9.18. 条件式. PostgreSQL 15.0文書