SQLにおけるCASE文(CASE式)は、SELECT文などのSQL文中で「条件分岐処理」を行うための文・命令です。
以下のようにSELECT文の中に組み込んで、他の列の値を条件にして異なる値を出力することが可能です。
SELECT ID,Name,Japanese, CASE WHEN Japanese >= 90 THEN '合格' WHEN Japanese < 90 THEN '不合格' ELSE null END AS Result FROM PointList; /* 結果(Result列の値がJapanese列の値によって決定される) +----+------+----------+--------+ | ID | Name | Japanese | Result | +----+------+----------+--------+ | 1 | 佐藤 | 100 | 合格 | | 2 | 鈴木 | 90 | 合格 | | 3 | 高橋 | 85 | 不合格 | | 4 | 中村 | 90 | 合格 | | 5 | 小林 | 70 | 不合格 | | 6 | 山口 | 90 | 合格 | | 7 | 田中 | 70 | 不合格 | | 8 | 伊藤 | 70 | 不合格 | +----+------+----------+--------+ */
このページではSQL初心者向けにCASE文の利用方法をわかりやすく丁寧に図解付き・サンプルコード付きで解説します。
データベースエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識です。是非最後までご覧ください。
SQL文の基本ルール(大文字/小文字の区別、コメントの付与など)を始めに学んでおきたい方は以下の記事を先にご覧ください。
【SQL】CASE文の使い方
CASE文は指定した条件に応じて出力結果を変える処理を行います。
まずは基本となる構文ルールから確認し、その後で実際にCASE文を利用したSQLのサンプルコードを学んでいきましょう。
CASE WHEN (条件式1) THEN (出力内容1) WHEN (条件式2) THEN (出力内容2) ~~~~~~~ ELSE (出力内容N) END
今回は以下のようなテーブルを例にCASE文を利用していきます。
テーブル定義:参考(CREATE TABLE)
CREATE TABLE PointList ( ID INT(3) NOT NULL PRIMARY KEY, Name VARCHAR(50) NOT NULL, Class VARCHAR(1), Japanese INT(3) DEFAULT '0', Math INT(3) DEFAULT '0', English INT(3) DEFAULT '0' ); /* +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | ID | int(3) | NO | PRI | NULL | | | Name | varchar(50) | NO | | NULL | | | Class | varchar(1) | YES | | NULL | | | Japanese | int(3) | YES | | 0 | | | Math | int(3) | YES | | 0 | | | English | int(3) | YES | | 0 | | +----------+-------------+------+-----+---------+-------+ */
利用するダミーレコード:参考(INSERT文)
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (1,'佐藤','A',100,100,85); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (2,'鈴木','A',90,70,70); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (3,'高橋','A',85,70,65); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (4,'中村','A',90,65,85); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (5,'小林','B',70,90,65); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (6,'山口','B',90,85,85); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (7,'田中','B',70,90,65); INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (8,'伊藤','B',70,90,65); SELECT * FROM PointList; /* +----+------+-------+----------+------+---------+ | ID | Name | Class | Japanese | Math | English | +----+------+-------+----------+------+---------+ | 1 | 佐藤 | A | 100 | 100 | 85 | | 2 | 鈴木 | A | 90 | 70 | 70 | | 3 | 高橋 | A | 85 | 70 | 65 | | 4 | 中村 | A | 90 | 65 | 85 | | 5 | 小林 | B | 70 | 90 | 65 | | 6 | 山口 | B | 90 | 85 | 85 | | 7 | 田中 | B | 70 | 90 | 65 | | 8 | 伊藤 | B | 70 | 90 | 65 | +----+------+-------+----------+------+---------+ */
CASE文を利用したSELECT文
CASE文はCASE式とも呼ばれ、SQLでは「式(=1つの値)」として扱われます。つまり、基本的にはSQLで定数が利用できるような場所にはどこにでも記載することが可能。
その中で最も一般的に利用されるのがSELECT文中で利用する方法です。
冒頭で例示したサンプルコードを見てみましょう。ここでは、SELECT句にCASE式を適用しています。
SELECT ID,Name,Japanese, CASE WHEN Japanese >= 90 THEN '合格' WHEN Japanese < 90 THEN '不合格' ELSE null END AS Result FROM PointList; /* 結果 +----+------+----------+--------+ | ID | Name | Japanese | Result | +----+------+----------+--------+ | 1 | 佐藤 | 100 | 合格 | | 2 | 鈴木 | 90 | 合格 | | 3 | 高橋 | 85 | 不合格 | | 4 | 中村 | 90 | 合格 | | 5 | 小林 | 70 | 不合格 | | 6 | 山口 | 90 | 合格 | | 7 | 田中 | 70 | 不合格 | | 8 | 伊藤 | 70 | 不合格 | +----+------+----------+--------+ */
CASE式は "WHEN" の後に記述した条件式の評価を行い、それに合致すれば "THEN" に記述した値を返します。合致しない場合は、次の条件に合致するか?を順次検証していく流れです。
どれにも合致しない場合は、"ELSE" に記述した内容が出力されます。
CASE文の "WHEN" の後ろには以下のように様々な条件を設定することも可能。
SELECT *, CASE WHEN Japanese+Math+English >= 270 THEN '合格' ELSE '不合格' END AS Result FROM PointList; /* 結果 +----+------+-------+----------+------+---------+--------+ | ID | Name | Class | Japanese | Math | English | Result | +----+------+-------+----------+------+---------+--------+ | 1 | 佐藤 | A | 100 | 100 | 85 | 合格 | | 2 | 鈴木 | A | 90 | 70 | 70 | 不合格 | | 3 | 高橋 | A | 85 | 70 | 65 | 不合格 | | 4 | 中村 | A | 90 | 65 | 85 | 不合格 | | 5 | 小林 | B | 70 | 90 | 65 | 不合格 | | 6 | 山口 | B | 90 | 85 | 85 | 不合格 | | 7 | 田中 | B | 70 | 90 | 65 | 不合格 | | 8 | 伊藤 | B | 70 | 90 | 65 | 不合格 | +----+------+-------+----------+------+---------+--------+ */
検索CASE式 vs 単純CASE式
CASE文(CASE式)は、実は二通りの記述方法が存在します。
検索CASE式
CASE WHEN (条件式1) THEN (出力内容1) WHEN (条件式2) THEN (出力内容2) ~~~~~~~ ELSE (出力内容N) END
単純CASE式
CASE (式) WHEN (値) THEN (出力内容1) WHEN (値) THEN (出力内容2) ~~~~~~~ ELSE (出力内容N) END
単純CASE式の記述方法がこちら。
SELECT ID,Name,Japanese, CASE Japanese WHEN 100 THEN '合格' ELSE '不合格' END AS Result FROM PointList; /* 結果 +----+------+----------+--------+ | ID | Name | Japanese | Result | +----+------+----------+--------+ | 1 | 佐藤 | 100 | 合格 | | 2 | 鈴木 | 90 | 不合格 | | 3 | 高橋 | 85 | 不合格 | | 4 | 中村 | 90 | 不合格 | | 5 | 小林 | 70 | 不合格 | | 6 | 山口 | 90 | 不合格 | | 7 | 田中 | 70 | 不合格 | | 8 | 伊藤 | 70 | 不合格 | +----+------+----------+--------+ */
ご覧のように、"CASE" の直後に判断対象のカラム名を。"WHEN" の後にそのカラムの値を記述しています。
ただし、単純CASE式はWHEN句ごとに異なるカラムの値を用いて条件分岐を行うたい場合には利用できないため、将来的に仕様変更が考えられるようなSQL文では用いない方が賢明です。
検索CASE式の方が汎用的で、単純CASE式とさほど記述方法も変わらない(=コーディングする際の負担とはならない)ため、基本的には検索CASE式を用いる方がおすすめです。
システムエンジニアを目指したい方は
システムエンジニアを目指す方や、IT知識を1から身につけたい方は以下のページをご覧ください。
正直どこから学び始めればよいかわからない。どのように勉強していけば、エンジニアとしてのスキルが磨けるか?が分からない・・・という方は必見です。
システムエンジニア向けに「できるエンジニア」になる方法を1から解説しておりますので、是非ご覧ください。