SQL
 Computer >> コンピューター >  >> プログラミング >> SQL

SQL CASE文とは?if/then風の条件分岐をクエリで実現する方法

データベースを操作していると、クエリの中で「もし〜ならば(if/then)」のような条件分岐処理を行いたい場面が出てきます。例えば、勤続1年以上の従業員の試用期間ステータスを一括で更新したい場合や、リーダーボードの上位3位以内に入ったプレイヤーに「勝者」のマークを付けたい場合などが挙げられます。

こうした処理をSQLで実現するには、CASE文を使用します。SQLのCASE文を使えば、Microsoft ExcelのIF関数と同じような感覚で、条件に応じた値の出し分けが可能になります。

本記事では、SQL CASE文の基本をわかりやすく解説し、クエリでの具体的な使い方を紹介します。さらに、複数条件を組み合わせたCASE文の書き方や、集計関数との併用方法についても取り上げます。

前提知識:SQLクエリの基本をおさらい

データベースから情報を取得するには、クエリ(問い合わせ)を記述します。クエリはほとんどの場合、取得したい列を指定するSELECT文から始まります。また、どのテーブルを対象にするかを指定するFROM句も通常含まれます。

SQLクエリの基本的な構文は以下のとおりです。

SELECT column_name FROM table_name WHERE conditions_are_met;

具体例を見てみましょう。次のクエリは、employeesテーブルから全従業員の名前を取得するものです。

SELECT name FROM employees;

このクエリを実行すると、次のような結果が返されます。

name
Luke
Mike
Hannah
Geoff
Alexis
Emma
Jonah
Adam

(8行)

複数の列を取得したい場合は、列名をカンマで区切って指定します。すべての列の情報を取得したい場合は、テーブル内の全列を表すアスタリスク(*)を使用します。

また、特定の条件に合致するレコードだけを絞り込みたいときは、WHERE句を使います。以下は、Albany支店に所属する従業員の名前を検索するクエリの例です。

SELECT name FROM employees WHERE branch = 'Albany';

実行結果は次のとおりです。

name
Emma
Jonah

(2行)

ここまでは比較的シンプルなクエリでした。では、クエリの実行時に「if/then」的な条件分岐を行いたい場合はどうすればよいのでしょうか。そこで活躍するのが、SQLのCASE文です。

SQL CASE文の基本

CASE文を使うと、SQLのコード内に条件分岐ロジックを組み込めます。例えば、「勤続5年以上の従業員全員に昇給を与えたい」といった場合に、CASE文が役立ちます。

SQL CASE文の基本構文は以下のとおりです。

SELECT column1_name,
	CASE WHEN column2_name = 'X' THEN 'Y'
		ELSE NULL END AS column3_name
	FROM table_name;

この構文には多くの要素が含まれているため、具体例で動きを確認しましょう。「今月の従業員賞(employee of the month)を5回より多く受賞した従業員全員に200ドルの昇給を与えたい」とします。これを実現するSQL文は次のようになります。

SELECT name,
	CASE WHEN employee_month_awards > 5 THEN 200
		ELSE NULL END AS pending_raise
	FROM employees;

このクエリ(検索CASE式)を実行すると、次の結果が返されます。

namepending_raise
Luke
Mike
Hannah
Geoff
Alexis
Emma200
Jonah
Adam200

(8行)

処理の流れを分解してみましょう。CASE文は各レコードを順にチェックし、条件式 employee_month_awards > 5 が真かどうかを評価します。条件が真であれば、pending_raise列に200という値が出力されます。偽の場合はNULL(空の値)がそのまま残ります。

最終的に、クエリは従業員名の一覧と、それぞれの予定昇給額を返します。

重要なポイントとして、SQL CASE文は元のテーブルに新しい列を追加するわけではないことに注意してください。CASE文はあくまでSELECTクエリの出力結果の中に列を作成するものであり、誰が昇給対象かを確認するために使われるものです。

なお、昇給対象外の従業員に対してNULLではなく別の値(例えば0)を表示したい場合は、ELSE句でNULLの代わりにその値を指定します。また、ORDER BY句を組み合わせれば、結果を任意の順序で並べ替えることも可能です。

複数条件を扱うSQL CASE文

CASE文は、同じクエリ内で複数回使用できます。例えば、「受賞歴3回以上の従業員には50ドルの昇給、5回を超える従業員には200ドルの昇給を与えたい」という場合、次のような文を書けます。

SELECT name,
	CASE WHEN employee_month_awards > 5 THEN 200
		WHEN employee_month_awards > 3 THEN 50
		ELSE 0 END AS pending_raise
	FROM employees;

このクエリの出力結果は次のとおりです。

namepending_raise
Luke50
Mike0
Hannah0
Geoff0
Alexis0
Emma200
Jonah50
Adam200

(8行)

この例では、CASE文は記述された順番に評価されます。まず「5回より多い」受賞者をチェックして昇給額を200に設定し、次に「3回より多い」受賞者をチェックして50に設定します。どの条件にも当てはまらない従業員は、ELSE句により0が設定されます。

ただし、このコードには改善の余地があります。評価順序に依存した書き方ではなく、条件同士が重複しないように記述する方が安全です。以下は、AND演算子を使って受賞回数の範囲を明示的にチェックする例です。

SELECT name,
	CASE WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
		WHEN employee_month_awards > 5 THEN 200
		ELSE 0 END AS pending_raise
	FROM employees;

このクエリは先ほどと同じ結果を返しますが、CASE文の記述順序に依存しないため、条件の書き間違いによるバグが発生しにくくなります。

集計関数と組み合わせたSQL CASE文

CASE文は、COUNTやSUMなどの集計関数と組み合わせることもできます。これは、特定の条件を満たす行だけをカウントしたい場合などに便利です。例えば、「200ドルのボーナスを受け取れる従業員が何人いるか」を調べたいときに活用できます。

集計関数とCASE文を組み合わせる際の構文は以下のとおりです。

SELECT column1_name,
	CASE WHEN column2_name = 'X' THEN 'Y'
		ELSE NULL END AS column3_name,
		COUNT(1) AS count
	FROM table_name
GROUP BY column3_name;

具体例として、「50ドル以上の昇給対象となる従業員が何人いるか」を調べたいとします。次のクエリでこの情報を取得できます。

SELECT 
	CASE WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
		WHEN employee_month_awards > 5 THEN 200
		ELSE 0 END AS pending_raise,
		COUNT(1) AS count
	FROM employees
GROUP BY pending_raise;

実行結果は次のとおりです。

pending_raisecount
503
03
2002

ご覧のとおり、このクエリは従業員ごとの予定昇給額と、その種類ごとの人数を返します。この例では、50ドルの昇給対象が3名、昇給なし(0ドル)が3名、200ドルの昇給対象が2名という結果になっています。

まとめ

本記事では、SQLにおけるCASE文の基本を解説し、クエリ内でif/thenロジックを実装する方法を紹介しました。さらに、複数条件の扱い方や集計関数との組み合わせについても触れました。

最後に、シンプルなCASE式を書く際のルールをおさらいしておきましょう。

  • CASE文はSELECT句の中に記述する
  • CASE文にはWHENTHENENDの各要素を必ず含める
  • 複数のWHEN句やELSE句は必要に応じて任意で使用できる
  • WHENTHENの間には、ANDORなどの条件式を組み込める

これで、あなたもプロのSQLエンジニアのようにCASE文を使いこなせるはずです。ぜひ実際のクエリで試してみてください。

  1. SQL Serverクエリストアとは?設定方法から実行プランの強制まで徹底解説

    Microsoft® SQL Server® のクエリストア(Query Store)は、その名のとおり、データベース上で実行されたクエリの履歴、ランタイム実行統計、実行プランを「保管庫」のように記録してくれる機能です。収集されたデータはディスク上に保存されるため、トラブルシューティングが必要になったときにいつでも参照でき、SQL Server を再起動してもデータは失われません。SQL Server 2016 で導入され、それ以降のすべてのエディションで利用可能なクエリストアを活用すれば、クエリプランの変更に起因するパフォーマンス問題の切り分けが格段に容易になります。 はじめに パフォーマン

  2. Oracle Database 19cのSQL検疫(SQL Quarantine)機能とは?リソースマネージャによる暴走クエリ対策の完全ガイド

    本記事では、Oracle Database 19cの新機能であるSQL検疫(SQL Quarantine)について詳しく解説します。Oracle® Resource Managerを使用すると、CPUやI/Oといったシステムリソースの使用量を制御・制限できます。さらに注目すべきは、定義された閾値を超える長時間実行クエリの実行自体を防止できる点です。 SQL検疫(SQL Quarantine)とは何か? 「検疫(Quarantine)」とは隔離を意味します。SQL検疫は、暴走クエリ(Runaway Query)がもたらすオーバーヘッドを排除するために使用できる、19cの新機能です。暴走クエリとは