skillup

技術ブログ

Database

CASE式のすすめ

投稿日:2016年11月2日 更新日:

SQL実践入門を7割がたぐらい終えたところで同著者の方の「達人に学ぶSQL徹底指南書」を学習しようと思っています。

この方の著書は気づいたら結構読んでましたね。

CASE式での注意ポイント

SQL実践入門でも書かれていましたが、条件分岐の中にはWHERE句でゴリゴリ書くよりもCASE式を使ったほうが有効なパターンがいくつかあります。

そんな使えるCASE式ですが、以下のことに注意。以前にも自分なりにこのエントリーで書いてますので、重複することあるかも。

同一条件で返すデータは統一させる

当たり前ですが、同一条件内で数値と文字列みたいな、そういうのはダメです。

ELSE~ENDの書き忘れ

ELSEは書かなくても動くっぽいですが、書いておいたほうがよいでしょう。ENDは書かないと動かないようです。ただし、本書では明示的に書くようにアドバイスをしています。エラーにならないけど結果が違うというケースが出てしまうからでしょう。

サンプル例

※著者の方のページに全部情報が載っているのでここ見たほうが早いかも(爆)。

http://mickindex.sakura.ne.jp/database/db_support_sinan.html

テーブル名 poptbl

pref_name | population
———–+————

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

よくあるケースとしては上記のようなテーブルで地方ごとに集計したい、といったときでしょう。こういったときに別カラム(地方コードなど)を追加して判別する方法もありますが、こういうときにこそダイレクトにCASE式が使えます。

上記のSQLで下記のような結果を出すことができます。

pref_name | district
———–+———-
徳島 | 四国
香川 | 四国
愛媛 | 四国
高知 | 四国
福岡 | 九州
佐賀 | 九州
長崎 | 九州
東京 | 関東
群馬 | 関東

あとはこれをGROUP BYしてSUMをとればいいのです。

district | sum
———-+—–
四国 | 650
関東 | 450
九州 | 600

カラムを増やさなくても見事にできました。

なおGROUP BYの部分にはSELECT式で作ったカラム名(districtをそのまま使えます。)

この書き方は便利ですが、厳密にいうと非推奨のようでMySQLやPostgresでは動きますが、他のデータベースでは動かないようです。

なお、階級ごとに分けるなんてこともできます。

city_rank | count
———–+——-
小都市 | 3
中都市 | 5
大都市 | 1

また下記のようなテーブル(PopTbl2)があり、

pref_name | sex | population
———–+—–+————
徳島 | 1 | 60
徳島 | 2 | 40
香川 | 1 | 100
香川 | 2 | 100
愛媛 | 1 | 100
愛媛 | 2 | 50
高知 | 1 | 100
高知 | 2 | 100
福岡 | 1 | 100
福岡 | 2 | 200
佐賀 | 1 | 20
佐賀 | 2 | 80
長崎 | 1 | 125
長崎 | 2 | 125
東京 | 1 | 250
東京 | 2 | 150

これを

pref_name| man | woman
徳島  | 60 | 40
・・・・・・

のように分けたいとします。1回のSQLで。

前段階として、男ならman列に出し、女ならwoman列に出すというのは下記のように書いてあげます。
この場合も下記のようにCASE式を使い、別の列に出力してあげればOKです。

※今回は条件判定をする対象列は一列ですが、2列に出すのでCASE式を2つに書きます。

pref_name | sex | men | women
———–+—–+—–+——-
徳島 | 1 | 60 | 0
徳島 | 2 | 0 | 40

この段階で上記のように出力することができます。

ここでさらに、これをpref_nameでSUMします。

pref_name | man | woman
———–+—–+——-
長崎 | 125 | 125
東京 | 250 | 150
香川 | 100 | 100
高知 | 100 | 100
徳島 | 60 | 40
愛媛 | 100 | 50
福岡 | 100 | 200
佐賀 | 20 | 80

プログラムと近いですが、一気にやらず一つずつ組み立てていくと楽でしょう。

-Database
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

herokuでMySQL

昨日に続き、heroku+MySQLのメモです。 herokuはディフォルトではPostgreSQLですが、アドオンを使うとMySQLも使えるようになります。 使い方ですが、herokuの管理画面でク …

no image

SQL基礎 case式について

case式に関して。 集約系の関数では複雑な処理を一気に行うことができる。 case式は1列のみ有効。複数の列に対して行うことはできない。 case ~ when ・・・thenではwhenが評価され …

no image

データベースのインデックスについて

今回はデータベースのインデックスに関して。 検索条件を早くする場合、何よりも速度が速くなるのはインデックスを張ることでしょう。 インデックスを張ることは単語を索引順に並べることですので、劇的に速度が向 …

no image

MySQLの大文字、小文字問題について

MySQLでテーブルを作る際にカラムに重複を許さない制約(unique)を振ることがあると思います。 数字の場合は問題ないのですが、文字列の場合、なんと英語の大文字と小文字が区別されません。 つまりa …

no image

MySQL.sockファイルに関して

朝出社してテストサーバーを見るといきなりサーバーが動いていないという事態が発生。 MySQLを起動しようとすると

なるメッセージがでて …

アーカイブ