🧚 お知らせ!Beekeeper Studioは高速でモダンなオープンソースのデータベースGUIです ダウンロード
2026年1月13日 著者: Matthew Rathbone

CASEはSQLクエリにif/then/elseのロジックを追加します。条件のリストを順に評価し、最初に真となった条件の結果を返します。例はPostgreSQL、MySQL、SQLite、SQL Serverで動作します。

CASEの使い方

CASEとENDの間にWHEN condition THEN resultのペアを並べます。CASEは最初に真となった条件の結果を返し、どれも真でなければELSEの値を返します。

CASE
  WHEN condition THEN result
  [WHEN condition THEN result ...]
  [ELSE result]
END
SELECT
  CASE
    WHEN 72 >= 90 THEN 'Hot'
    WHEN 72 >= 60 THEN 'Mild'
    ELSE 'Cold'
  END;
-- Output: Mild

すべての条件が同じ値との等価比較なら、より短い「単純」形式でその値を一度だけ指定できます。

SELECT
  CASE 'amber'
    WHEN 'green' THEN 'Go'
    WHEN 'amber' THEN 'Slow down'
    WHEN 'red' THEN 'Stop'
    ELSE 'Unknown'
  END;
-- Output: Slow down

実際のクエリでは条件でカラムを評価し、CASEは結果に新しいカラムを追加します。

-- Input: orders
-- order_id | amount
-- ---------+--------
-- 1001     | 45.00
-- 1002     | 100.00
-- 1003     | 349.99
-- 1004     | 1250.00

SELECT
  order_id,
  amount,
  CASE
    WHEN amount < 100 THEN 'Small'
    WHEN amount < 500 THEN 'Medium'
    ELSE 'Large'
  END AS order_size
FROM orders;

-- Output:
-- order_id | amount  | order_size
-- ---------+---------+-----------
-- 1001     | 45.00   | Small
-- 1002     | 100.00  | Medium
-- 1003     | 349.99  | Medium
-- 1004     | 1250.00 | Large

知っておくべきルール

  • 最初に真となった条件が採用されます。条件は上から順に評価されるため、最も範囲の狭い条件を先に書きます。上の例では、amount < 100が偽でamount < 500が真なので、100.00はMediumになります。順序を誤ると、小さい金額は本来の分岐に到達しません。
SELECT
  CASE
    WHEN 45 < 500 THEN 'Medium'
    WHEN 45 < 100 THEN 'Small'  -- can never win
    ELSE 'Large'
  END;
-- Output: Medium
  • ELSEがない場合、一致しなければNULLになります。
SELECT CASE WHEN 72 >= 90 THEN 'Hot' END;
-- Output: NULL
  • NULLの判定にはIS NULLを使います。NULL = NULLは真にならないため、単純形式ではNULLに一致させられません。検索形式を使ってください。
SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'no match' END;
-- Output: no match

SELECT CASE WHEN NULL IS NULL THEN 'matched' ELSE 'no match' END;
-- Output: matched
  • すべての結果は互換性のある型である必要があります。1つのCASEで数値とテキストを混在させるとPostgreSQLやSQL Serverではエラーになるため、数値をキャストします。
-- Input: products
-- name         | stock
-- -------------+------
-- Desk Lamp    | 12
-- Office Chair | 0

SELECT name, CASE WHEN stock > 0 THEN stock ELSE 'Sold out' END AS stock
FROM products;
-- PostgreSQL: ERROR: invalid input syntax for type integer: "Sold out"
-- SQL Server: Conversion failed when converting the varchar value 'Sold out' to data type int.

-- (in MySQL, cast with CAST(stock AS CHAR))
SELECT
  name,
  CASE WHEN stock > 0 THEN CAST(stock AS VARCHAR(10)) ELSE 'Sold out' END AS stock
FROM products;

-- Output:
-- name         | stock
-- -------------+---------
-- Desk Lamp    | 12
-- Office Chair | Sold out

別の構文

条件が1つだけの場合は、より短い関数もよく使われます。

-- MySQL
SELECT IF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild

-- SQL Server and SQLite
SELECT IIF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild

よく使うCASE式の省略形となる関数が他に2つあります。COALESCE(nickname, name)はCASE WHEN nickname IS NOT NULL THEN nickname ELSE name ENDと同じ意味で、NULLIF(a, b)はCASE WHEN a = b THEN NULL ELSE a ENDと同じ意味です。前者についてはSQL COALESCEガイドをご覧ください。

MySQLにはストアドプロシージャ用のCASE文もあり、END CASEで終わります。この記事ではクエリで使うCASE式を扱います。

CASEはどんなときに使う?

CASEは式なので、値を書ける場所ならどこでも使えます。SELECTリスト、ORDER BYやGROUP BY、集計関数の中などです。WHEREでも使えますが、そこでは通常のANDやORの方がわかりやすいことが多いです。ほとんどの用途は次の5つのいずれかに当てはまります。

数値を範囲に分ける

数値を価格帯、注文サイズ、年齢層、成績などの区分に変換します。条件を尺度の一方の端からもう一方へ順に書けば、最初の一致が正しい区分になります。

コードをラベルに変換する

データベースには'A'、'ENG'、'gold'のような短いコードが保存されていますが、人が見たいのは言葉です。単純形式のCASEで各コードをラベルや割引率などの値に対応付け、想定外のコードはELSEで受け止めます。

一部の行だけを数える・合計する

COUNTやSUMの中にCASEを入れると、条件を満たす行だけを数えたり合計したりできます。COUNT(CASE WHEN ... THEN 1 END)が機能するのは、一致しない行がNULLになり、COUNTがNULLを無視するためです。条件ごとに集計を1つずつ書けば複数の合計を横に並べられ、これがSQLでピボットテーブルを作る方法です。

欠損値を扱う

優先順にカラムのNULLを確認し、すべて空ならラベルを返します。単純な代替値ならCOALESCEの方が短く書けます。欠損の種類ごとに異なる結果が必要なときはCASEが適しています。

独自の順序で並べ替える

服のサイズ、チケットの優先度、おすすめ商品を先頭にしたリストなど、アルファベット順や数値順では合わないものもあります。ORDER BYでCASEを使えば、各値を好きな位置に配置できます。

CASEの実例

部門と価格で商品を分類する

結果自体をCASEにできるので、部門ごとに独自の価格帯を設定できます。

-- Input: products
-- product_name     | category    | price
-- -----------------+-------------+--------
-- Laptop Pro 14    | Electronics | 1499.00
-- Wireless Earbuds | Electronics | 129.00
-- Leather Jacket   | Clothing    | 349.00
-- Cotton T-Shirt   | Clothing    | 19.99
-- Coffee Mug       | Kitchen     | 12.50

SELECT
  product_name,
  CASE category
    WHEN 'Electronics' THEN
      CASE
        WHEN price > 1000 THEN 'Premium Electronics'
        ELSE 'Standard Electronics'
      END
    WHEN 'Clothing' THEN
      CASE
        WHEN price > 200 THEN 'Designer Clothing'
        ELSE 'Regular Clothing'
      END
    ELSE 'Other Products'
  END AS product_class
FROM products;

-- Output:
-- product_name     | product_class
-- -----------------+---------------------
-- Laptop Pro 14    | Premium Electronics
-- Wireless Earbuds | Standard Electronics
-- Leather Jacket   | Designer Clothing
-- Cotton T-Shirt   | Regular Clothing
-- Coffee Mug       | Other Products

2階層を超えると、ネストしたCASEは読みにくくなります。参照テーブルを作ってJOINする方が通常はわかりやすいです。

顧客ランク別に割引を適用する

各ランクコードを割引率に対応付け、ランクのない顧客は割引なしとします。

-- Input: customers
-- id | customer_name | tier
-- ---+---------------+-------
-- 1  | Maya Brooks   | gold
-- 2  | Leo Martin    | silver
-- 3  | Ava Kim       | bronze
-- 4  | Noah Price    | NULL

-- Input: orders
-- id  | customer_id | order_total
-- ----+-------------+------------
-- 101 | 1           | 200.00
-- 102 | 2           | 150.00
-- 103 | 3           | 80.00
-- 104 | 4           | 60.00

SELECT
  customer_name,
  order_total,
  ROUND(order_total * CASE tier
    WHEN 'gold' THEN 0.15
    WHEN 'silver' THEN 0.10
    WHEN 'bronze' THEN 0.05
    ELSE 0
  END, 2) AS discount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.id;

-- Output:
-- customer_name | order_total | discount
-- --------------+-------------+---------
-- Maya Brooks   | 200.00      | 30.00
-- Leo Martin    | 150.00      | 15.00
-- Ava Kim       | 80.00       | 4.00
-- Noah Price    | 60.00       | 0.00

月別売上をカラムにピボットする

月ごとにSUM(CASE ...)を1つずつ書くと、売上の行が月別のカラムに変わります。

-- Input: sales
-- product_category | sale_date  | amount
-- -----------------+------------+-------
-- Books            | 2026-01-12 | 40.00
-- Games            | 2026-01-20 | 60.00
-- Books            | 2026-02-03 | 25.00
-- Books            | 2026-03-15 | 30.00
-- Games            | 2026-03-28 | 75.00

SELECT
  product_category,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_category
ORDER BY product_category;

-- Output:
-- product_category | jan_sales | feb_sales | mar_sales
-- -----------------+-----------+-----------+----------
-- Books            | 40.00     | 25.00     | 30.00
-- Games            | 60.00     | 0         | 75.00

SQL ServerではEXTRACTの代わりにMONTH(sale_date) = 1を、SQLiteではstrftime('%m', sale_date) = '01'を使います。

欠損値と空文字を区別する

インポートしたデータにはNULLと空文字の両方が含まれていることがよくあります。CASEでそれぞれにラベルを付ければ、何をクリーンアップすべきかがわかります。

-- Input: users
-- id | middle_name
-- ---+------------
-- 1  | Rose
-- 2  |
-- 3  | NULL

SELECT
  id,
  CASE
    WHEN middle_name IS NULL THEN 'Missing'
    WHEN middle_name = '' THEN 'Empty'
    ELSE middle_name
  END AS middle_name
FROM users;

-- Output:
-- id | middle_name
-- ---+------------
-- 1  | Rose
-- 2  | Empty
-- 3  | Missing

各カテゴリに並び順を割り当て、その中で名前順に並べ替えます。

-- Input: products
-- product_name | category
-- -------------+------------
-- Wool Scarf   | Sale
-- Desk Lamp    | Featured
-- Bike Helmet  | Clearance
-- Smart Watch  | New Arrival
-- Air Fryer    | Featured

SELECT product_name, category
FROM products
ORDER BY
  CASE category
    WHEN 'Featured' THEN 1
    WHEN 'New Arrival' THEN 2
    WHEN 'Sale' THEN 3
    ELSE 4
  END,
  product_name;

-- Output:
-- product_name | category
-- -------------+------------
-- Air Fryer    | Featured
-- Desk Lamp    | Featured
-- Smart Watch  | New Arrival
-- Wool Scarf   | Sale
-- Bike Helmet  | Clearance

CASEについてさらに詳しく

このブログの記事:

公式ドキュメント:

Beekeeper Studioは無料のオープンソースのデータベースGUIです

これまで使った中で最高のSQLクエリ&エディタツールです。データベースの管理に必要なものがすべて揃っています。 - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studioは高速で直感的、そして使いやすいツールです。多数のデータベースに対応し、Windows、Mac、Linuxで快適に動作します。

BeekeeperのLinux版は100%フル機能。手抜きも機能の妥協も一切ありません。

Beekeeper Studio 利用者の声

★★★★★
「Beekeeper Studioは以前のSQLワークフローを完全に置き換えました。高速で直感的で、データベース作業が再び楽しくなりました。」
— Alex K.、データベース開発者
★★★★★
「多くのデータベースGUIを試しましたが、Beekeeperは機能とシンプルさのバランスが完璧です。とにかくちゃんと動きます。」
— Sarah M.、フルスタックエンジニア