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

SQL 更新系に関して

SQL実践入門、残り2章になりましたが、いやーむずいっす。 今回は9章を進めていますがSQLはもともと検索を主な用途として発展したため、SELECT文の使用がメインになります。 ですが、UPDATE文 …

no image

テーブル設計に関するメリデメ

昨日も書いた記事なんですが、基本的に実装にしても設計にしてもこれが最強っていう手法はなくて(あったとしたら全員がそれを使うのでそもそも選択肢という概念がなくなる・・)メリットデメリットをしっかりと考慮 …

no image

JSON型の検索

複数のタグなどを入れる場合、JSON型のカラムやデータなどを入れることがあるかと思いますが、ここから検索できるということが昨日わかりましたので、メモしておきます。 SQLServerで発見しましたが、 …

no image

Cakeでのリレーションについて

いまさらながらCakeのリレーションについての復習。 基本から。 Contents1 基本的なリレーション1.1 1対N1.2 N対11.3 動的な紐づけ 基本的なリレーション 下記のようなテーブル構 …

no image

JPAでのデータベースとの同期

このブログでも何回か書いてきたJPAですが、新規レコードをインサートさせた際IDを取得し、そのIDをもとに何らかのキーを作る、そういう処理があったので紹介させていただきます。 何回か書いてますが、JP …

アーカイブ