SQLのCASE式

CASE式を使用するとSQL文の中で条件に応じた分岐を実現出来る。

CASE式の評価は真になるWHEN句が見つかった時点で打ち切られる。
以降のWHEN句は無視されるので、それを意識して記述する必要がある。

ELSE句は条件に一致するものがない場合のデフォルト値を示す。
ELSE句が宣言されていなければ「NULL」が返ってくる。

SELECT
  test_table.*,
  CASE
    WHEN birth >= '2020/01/01' THEN '2020年代'
    WHEN birth >= '2010/01/01' THEN '2010年代'
    WHEN birth >= '2000/01/01' THEN '2000年代'
    ELSE 'いずれでもない'
  END AS "生年月日で年代判定"
FROM
  test_table

+------+--------+------------+--------------+-----------------------------+
| id   | name   | birth      | address      | 生年月日で年代判定          |
+------+--------+------------+--------------+-----------------------------+
| 1001 | 山田   | 1998-01-05 | 東京都       | いずれでもない              |
| 1002 | 田中   | 2003-06-01 | 神奈川県     | 2000年代                    |
| 1003 | 鈴木   | 2008-11-20 | 埼玉県       | 2000年代                    |
| 1004 | 宮田   | 2016-03-15 | 東京都       | 2010年代                    |
| 1005 | 鈴木   | 2012-04-10 | 東京都       | 2010年代                    |
| 1006 | 佐藤   | 2021-05-02 | 埼玉県       | 2020年代                    |
| 1007 | 高橋   | 2001-12-09 | 神奈川県     | 2000年代                    |
| 1008 | 池田   | 1999-02-13 | 埼玉県       | いずれでもない              |
| 1009 | 鈴木   | 2022-06-09 | 東京都       | 2020年代                    |
| 1010 | 田中   | 2000-08-21 | 神奈川県     | 2000年代                    |
+------+--------+------------+--------------+-----------------------------+


CASE式はネストさせる事も出来る。

SELECT
  test_table.*,
  CASE
    WHEN address LIKE '東京%' THEN
      CASE
        WHEN birth >= '2020/01/01' THEN '東京の2020年代'
        WHEN birth >= '2010/01/01' THEN '東京の2010年代'
        WHEN birth >= '2000/01/01' THEN '東京の2000年代'
        ELSE '東京で年代はいずれでもない'
      END
    WHEN address LIKE '埼玉%' THEN
      CASE
        WHEN birth >= '2020/01/01' THEN '埼玉の2020年代'
        WHEN birth >= '2010/01/01' THEN '埼玉の2010年代'
        WHEN birth >= '2000/01/01' THEN '埼玉の2000年代'
        ELSE '埼玉で年代はいずれでもない'
      END
    ELSE
      CASE
        WHEN birth >= '2020/01/01' THEN '東京・埼玉以外の2020年代'
        WHEN birth >= '2010/01/01' THEN '東京・埼玉以外の2010年代'
        WHEN birth >= '2000/01/01' THEN '東京・埼玉以外の2000年代'
        ELSE '東京・埼玉以外で年代はいずれでもない'
      END
  END AS "住所と生年月日の組合せ"
FROM
  test_table

+------+--------+------------+--------------+-------------------------------+
| id   | name   | birth      | address      | 住所と生年月日の組合せ        |
+------+--------+------------+--------------+-------------------------------+
| 1001 | 山田   | 1998-01-05 | 東京都       | 東京で年代はいずれでもない    |
| 1002 | 田中   | 2003-06-01 | 神奈川県     | 東京・埼玉以外の2000年代      |
| 1003 | 鈴木   | 2008-11-20 | 埼玉県       | 埼玉の2000年代                |
| 1004 | 宮田   | 2016-03-15 | 東京都       | 東京の2010年代                |
| 1005 | 鈴木   | 2012-04-10 | 東京都       | 東京の2010年代                |
| 1006 | 佐藤   | 2021-05-02 | 埼玉県       | 埼玉の2020年代                |
| 1007 | 高橋   | 2001-12-09 | 神奈川県     | 東京・埼玉以外の2000年代      |
| 1008 | 池田   | 1999-02-13 | 埼玉県       | 埼玉で年代はいずれでもない    |
| 1009 | 鈴木   | 2022-06-09 | 東京都       | 東京の2020年代                |
| 1010 | 田中   | 2000-08-21 | 神奈川県     | 東京・埼玉以外の2000年代      |
+------+--------+------------+--------------+-------------------------------+


集計関数を組み合わせる事で、条件に該当するデータの集計も出来る。

SELECT
   SUM(
        CASE
          WHEN address LIKE '東京%' THEN 1
          ELSE 0
        END
      ) AS "東京の人数"
 , SUM(
        CASE
          WHEN address LIKE '埼玉%' THEN 1
          ELSE 0
        END
      ) AS "埼玉の人数"
 , MAX(
        CASE
          WHEN address LIKE '東京%' THEN birth
          ELSE NULL
        END
      ) AS "東京内で最大の生年月日"
 , MAX(
        CASE
          WHEN address LIKE '埼玉%' THEN birth
          ELSE NULL
        END
      ) AS "埼玉内で最大の生年月日"
FROM
  test_table

+------------+------------+------------------------+------------------------+
| 東京の人数 | 埼玉の人数 | 東京内で最大の生年月日 | 埼玉内で最大の生年月日 |
+------------+------------+------------------------+------------------------+
|          4 |          3 | 2022-06-09             | 2021-05-02             |
+------------+------------+------------------------+------------------------+

タイトルとURLをコピーしました