0Pricing
SQL Academy · レッスン

ORDER BYと集約でCASEを使う

条件付きの並べ替えと集計を行います。

「ORDER BYと集約でCASEを使う」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

カスタム優先度で並べ替える

SQLのORDER BY句は通常、列の自然な値に基づいて行を並べ替えます。しかし、ORDER BYの内部にCASE式を記述すれば、1つの列だけでは実現できない完全にカスタムな並べ替え順を作成できます。

この方法は、元のデータ値ではなく業務ルールによって優先順位が決まる場合に有効です。

SELECT product_name, status
FROM products
ORDER BY
  CASE status
    WHEN 'urgent'   THEN 1
    WHEN 'active'   THEN 2
    WHEN 'pending'  THEN 3
    ELSE                 4
  END;

ORDER BY内のCASEの仕組み

データベースがORDER BY CASE ... ENDを評価すると、各行について整数(または比較可能な値)が計算されます。その後、行は元の列の値ではなく、この計算値に基づいて並べ替えられます。元の列に加えて使うこともできます。

CASE式は保存されず、クエリの実行中だけ存在します。

SELECT order_id, priority
FROM orders
ORDER BY
  CASE priority
    WHEN 'high'   THEN 1
    WHEN 'medium' THEN 2
    WHEN 'low'    THEN 3
    ELSE               9
  END,
  order_id;

NULLを明示的に並べ替える

デフォルトでは、NULLを並べ替え結果の先頭と末尾のどちらに置くかがデータベースによって異なります。ORDER BY内のCASEを使えば、データベースエンジンに関係なく、NULLを置く位置を正確に決められます。

SELECT employee_name, manager_id
FROM employees
ORDER BY
  CASE WHEN manager_id IS NULL THEN 0 ELSE 1 END,
  manager_id;

条件付きの昇順と降順

ORDER BY内のCASEは、条件付きの並べ替え方向を実現することもできます。カテゴリ値を負の数に対応付けると、他のグループは通常の順序のまま、特定のグループだけ実質的に並べ替え順を逆にできます。

これは、1つの結果セット内で行の種類ごとに異なる並べ替えロジックが必要な場合に便利です。

SELECT task_name, due_date, is_overdue
FROM tasks
ORDER BY
  CASE WHEN is_overdue = 1 THEN 0 ELSE 1 END,
  due_date;

COUNT内のCASE

COUNTなどの集約関数の内部にCASE式を記述できます。数えたい行にはNULL以外の値を返し、除外したい行にはNULLを返すのがポイントです。COUNTはNULLを無視するためです。

SELECT
  COUNT(CASE WHEN status = 'active'   THEN 1 END) AS active_count,
  COUNT(CASE WHEN status = 'inactive' THEN 1 END) AS inactive_count
FROM users;

SUM内のCASE — 条件付きの合計

SUMの内部にCASEを記述すると、条件が真の場合にだけ値を加算し、一致しない行を0として扱えます。これは、1つの列を複数の指標列に分けるピボット形式のレポートで非常によく使われるパターンです。

SELECT
  SUM(CASE WHEN region = 'North' THEN sales_amount ELSE 0 END) AS north_total,
  SUM(CASE WHEN region = 'South' THEN sales_amount ELSE 0 END) AS south_total,
  SUM(CASE WHEN region = 'East'  THEN sales_amount ELSE 0 END) AS east_total
FROM sales;

CASEによる条件付きAVG

同じパターンはAVGでも使用できます。AVGはNULLを無視するため、除外したい行にNULLを返せば、一致する行だけの平均を計算できます。サブクエリは必要ありません。

SELECT
  AVG(CASE WHEN department = 'Engineering' THEN salary END) AS avg_eng_salary,
  AVG(CASE WHEN department = 'Marketing'   THEN salary END) AS avg_mkt_salary
FROM employees;

CASEでグループ化する — 行をバケット化する

GROUP BYまたはSELECTリストでCASEを使用して、連続した値をカテゴリに分類し、その後で各バケットを集約できます。これにより、元のデータを変更せずに数値列をラベル付きのグループに変換できます。

SELECT
  CASE
    WHEN age < 18             THEN 'Under 18'
    WHEN age BETWEEN 18 AND 35 THEN '18-35'
    WHEN age BETWEEN 36 AND 55 THEN '36-55'
    ELSE                            '56+'
  END AS age_group,
  COUNT(*) AS user_count
FROM users
GROUP BY
  CASE
    WHEN age < 18             THEN 'Under 18'
    WHEN age BETWEEN 18 AND 35 THEN '18-35'
    WHEN age BETWEEN 36 AND 55 THEN '36-55'
    ELSE                            '56+'
  END;

別名を使う場合とCASEを繰り返す場合

SELECTとGROUP BYの両方で長いCASE式を繰り返すのは冗長です。一部のデータベース(MySQL、回避策を使ったPostgreSQL)ではORDER BYで別名を参照できますが、GROUP BYでは参照できません。最も安全で移植性の高い方法は、クエリをサブクエリまたはCTEで囲み、そこで別名を使ってGROUP BYすることです。

WITH scored AS (
  SELECT
    customer_id,
    CASE
      WHEN total_spent >= 1000 THEN 'Gold'
      WHEN total_spent >= 500  THEN 'Silver'
      ELSE                          'Bronze'
    END AS tier
  FROM customers
)
SELECT tier, COUNT(*) AS customer_count
FROM scored
GROUP BY tier
ORDER BY
  CASE tier
    WHEN 'Gold'   THEN 1
    WHEN 'Silver' THEN 2
    ELSE               3
  END;

ORDER BY CASEとASC / DESCを組み合わせる

CASE式の後にもASCまたはDESCを付けられます。また、カンマで区切って追加のソート列を指定することもできます。CASEで計算したスコアは最初のソートキーにすぎず、その後の列で通常どおり同順位を解消します。

SELECT
  ticket_id,
  category,
  created_at
FROM support_tickets
ORDER BY
  CASE category
    WHEN 'billing'  THEN 1
    WHEN 'outage'   THEN 2
    WHEN 'feature'  THEN 3
    ELSE                 4
  END ASC,
  created_at ASC;

実世界の例 — 売上ダッシュボード

ここでは、CASE に基づく集計と CASE に基づく並べ替えを組み合わせた、現実的なクエリを見てみましょう。このクエリは地域ごとの売上概要を作成し、最も売上の高い地域が常に先頭に表示され、「Other」が最後になるように並べ替えます。

SELECT
  CASE
    WHEN region IN ('North', 'South', 'East', 'West') THEN region
    ELSE 'Other'
  END AS region_label,
  SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) AS completed_sales,
  COUNT(CASE WHEN status = 'refunded' THEN 1 END)           AS refund_count
FROM orders
GROUP BY
  CASE
    WHEN region IN ('North', 'South', 'East', 'West') THEN region
    ELSE 'Other'
  END
ORDER BY completed_sales DESC;

理解度チェック

ORDER BY や集計関数の中で CASE を使う方法を理解できているか確認しましょう。

レッスンのまとめ

このレッスンでは、CASE を ORDER BY や集計関数と組み合わせる方法を学びました。

  • ORDER BY の中の CASE — 行に独自の並べ替え用スコアを割り当て、NULL の表示位置を制御し、1つのクエリで複数の並べ替えルールを組み合わせます。
  • COUNT の中の CASE — 含める行には NULL ではない値を返し、除外する行には暗黙的または明示的に NULL を返します。
  • SUM / AVG の中の CASE — ELSE の値として 0 または NULL を使い、1回の処理で条件付きの合計や平均を作成します。
  • GROUP BY の中の CASE — 連続値やカテゴリ値を、集計用のラベル付きグループに分類します。

これらのパターンを使うと、多くのサブクエリが不要になり、通常の SQL でピボット形式のレポートを簡単に作成できます。

よくある質問

「ORDER BYと集約でCASEを使う」レッスンは無料ですか?

はい。「ORDER BYと集約でCASEを使う」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「ORDER BYと集約でCASEを使う」で何を学びますか?

条件付きの並べ替えと集計を行います。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ORDER BYと集約でCASEを使う」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. CASE式
  2. 検索CASEと単純CASE
  3. データの分類とラベル付け
  4. ORDER BYと集約でCASEを使う
← SQL Academyに戻る