5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SQLのCASE式をざっくりと理解する

Last updated at Posted at 2020-06-16

SQLのCASE式は便利です。しかし、どこが便利なのかよく分からなかったので、ざっくりとまとめてみました。

CASE式のサンプル

対象テーブル

都道府県別の人口テーブルを対象にします。

pref_name population
佐賀 100
徳島 100
愛媛 150
東京 400
福岡 300
群馬 500
長崎 200
香川 200
高知 200

欲しい結果

九州、四国、その他、という3つのラベルを作り、作ったラベルごとに人口を集計します。

district sum(population)
九州 600
四国 650
その他 900

実行SQL

select
  case pref_name
    when '徳島' then '四国'
    when '香川' then '四国'
    when '愛媛' then '四国'
    when '高知' then '四国'
    when '福岡' then '九州'
    when '佐賀' then '九州'
    when '長崎' then '九州'
    else 'その他' end as district, -- district means parts of nation
  sum(population)
from poptbl
group by district
;

CASE式でやっていることのイメージ

image.png

つまり、CASE式がやっていることは、データのラベルを読みかえることだと言えます。
こちらを踏まえて、いくつか具体例を見ていきましょう。

例2.データを横持ちにして集計する

やりたいこと

今度は、性別の列を設けて、都道府県別の性別ごとの人口を表現するテーブルにしました。
sex .. 1 が男、sex .. 2が女を指します。

pref_name sex population
佐賀 1 20
佐賀 2 80
徳島 1 60
徳島 2 40
愛媛 1 100
愛媛 2 50
東京 1 210
東京 2 190
福岡 1 100
福岡 2 200
群馬 1 240
群馬 2 260
長崎 1 150
長崎 2 50
香川 1 100
香川 2 100
高知 1 100
高知 2 100

こちらのテーブルから、さきほど作った新しい集合を、男女別に適用してみましょう。

結果のイメージ

徳島、香川、愛媛、高知を比較用に新しく用意しました。
その他と九州を削り、四国と、total(すべて)を追加しました。

sex tokushima kagawa ehime kochi shikoku total
60 100 100 100 360 1080
40 100 50 100 290 1070

実行SQL

select
  case when sex = '1' then '男' else '女' end as sex,
  sum(case when pref_name = '徳島' then population else 0 end) as tokushima,
  sum(case when pref_name = '香川' then population else 0 end) as kagawa,
  sum(case when pref_name = '愛媛' then population else 0 end) as ehime,
  sum(case when pref_name = '高知' then population else 0 end) as kochi,
  sum(case when pref_name in ('徳島', '香川', '愛媛', '高知') then population else 0 end) as shikoku,
  sum(population) as total
from
  poptbl2
group by sex;

SQLのポイント

in句を使って、四国に読みかえるデータをまとめて記述しています。

  sum(case when pref_name in ('徳島', '香川', '愛媛', '高知') then population else 0 end) as shikoku,

また、すべて(total)については、条件式が不要なので、pref_nameをすべて集計しています。

  sum(population) as total

こうしてみると、CASE式というのは、ExcelのVLookupに何となく似ているように思えます。

SQLのイメージ

image.png

例3.任意のソート順を実現する

データのラベルを読みかえる、というCASE式の特徴をよく現したのがこの方法だと思います。

やりたいこと

人事評価のランキングテーブルを作りました。データの中身に、そこまで意味はありません。
こちらのデータのidの順番を、任意の値に変更してみましょう 🍌

id num
A 1
A 2
A 3
B 1
N 1
N 2

結果のイメージ

任意の値に変わりましたね 🍌🍌🍌

id num
B 1
A 1
N 1
A 2
N 2
A 3

実行SQL

select
  id,
  num
from
  ranks
order by
  case
    when id = 'B' and num = 1 then 1
    when id = 'A' and num = 1 then 2
    when id = 'N' and num = 1 then 3
    when id = 'A' and num = 2 then 4
    when id = 'N' and num = 2 then 5
    when id = 'A' and num = 3 then 6
    else null end
;

SQLのポイント

order by にCASE式を導入していることがポイントです。then の後の数字を付けることで、レコードをラベルとして読み替えているのです。

order by
  case
    when id = 'B' and num = 1 then 1

order by は、読み替えられたデータの順番でなされます。

SQLのイメージ

image.png

おわりに - CASE式は何が便利か -

CASE式について、何が便利なのかを「ラベルの読み替え」という観点から見てみました。ラベルを読みかえると、既存のデータに独自のフラグを立てることが可能となり、立てたフラグの単位で集合演算を行えます。CASE式は、この点が便利だとわかりました。

なお、CASE式は、構文によってうまく動かないことがあるとのことです。ですので、構文を検証する記事も書きました。もし宜しければ、併せてご覧ください。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?