MySQL 条件分岐 case

スポンサーリンク
スポンサーリンク

条件分岐

MySQLでは条件分岐に case式を使います。

皆さんがよく使われているExcel・c言語では条件分岐にif文が使用されます。

その他マイツールというソフトにも使用されるif文がありますが、

SQLの構文からするとマイツールで使用される構文が一番SQLに近い記述の仕方です。

余談となりましたが、

条件分岐は、どんな言語でも用いられ、かなり必要度の高い関数ですので

各言語の条件式はしっかりとマスターしましょう。

例えば、テストの点数に例えると、

点数が90点以上だったら、Aと出力

点数が80点以上だったら、Bと出力

など、場合分けすることを条件分岐といいます。

case式の構文

case
 when 条件式1 then 値1   /* 条件式1がtrue(真)なら値1 */
 [when 条件式2 then 値2]   /* 条件式2がtrue(真)なら値2 */
 [else 値3]               /* どれにも当てはまらなければ値3 */
end

[]の部分は省略可能。

cace式サンプル

ランク分け

変数Xが10の場合を例にすると

case
 when x >= 10 then 'A'  ←適用(条件が成り立つ)
 when x >= 5 then 'B'   ←パス
 else 'C'         ←パス
end

上記の場合だと、case式の結果は ‘A’ になります。

※case式では、最初に条件に合致したブロックだけが実行されます。

変数xが5の場合だとcase式の結果は ‘B’ になります。

変数xが4の場合だとcase式の結果は ‘C’ になります。

それでは、以下の内容で、条件分岐してみます。

ユーザーを累計注文回数でランク分けします。

  • A:5回以上
  • B:2回以上
  • C:1回

必要情報

  • ユーザーID
  • 累計注文回数
  • ユーザーランク(AorBorC)

結合するテーブルを以下のテーブル名とした場合。

ユーザーテーブル(users)

  • 列名(user_id)

オーダーテーブル(orders)

  • 列名(id)

select
   u.id,       /* 出力する列を指定 user_id */
   count(*)          /* 注文回数 */
from
   users as u
inner join
   orders as o
on u.id = o.user_id /* 結合条件を指定 */
group by u.id; /* ユーザーidごとに集約 */

ここまででユーザーテーブルのuser_idとオーダーテーブルのidが結合されユーザーidごとにカウントされます。

※ユーザーIDにオーダーIDを紐づけしているので、一度も注文のないユーザーIDは出力されません。

次にcase式を使って条件を指定し注文回数によってランク分けをします。

条件を以下のようにした場合

  • 5回以上=A
  • 2回以上=B
  • 上記でない場合=C

このような記述になります。

select
   u.id as user_id,
   count(*) as num,
   case
     when count(*) >= 5 then 'A'
     when count(*) >= 2 then 'B'
     else 'C'
   end as user_rank
from
     users as u
inner join
    orders as o
on u.id = o.user_id
group by u.id;

実行結果は↓

これでは少し見ずらいので、order by句を使ってランクごとに並び替えしましょう!

group by句の後に以下のコードを追記します。

order by user_rank asc;

※ascは省略可です。

これで見やすくなりましたね。

nullを0に置き換える

以下のように外部接続するとNULLが返されているデータがあるのがわかると思います。

select
   p.id,
   p.name,
   sum( pd.product_qty) as num
from
   products p
left outer join
   order_details pd
on p.id = pd.product_id
group by p.id;

NULLを「0」に置き換えます。
追記した部分は太字で記載していますので参考にしてください。

as numendの後に移動します。

select
   p.id,
   p.name,
   case
   when sum(pd.product_qty)  is null then 0
   else sum(pd.product_qty)
   end as num  /*as numはendの後に移動 */
from
   products p
left outer join
   order_details pd
on p.id = pd.product_id
group by p.id;

にほんブログ村 IT技術ブログへ

スポンサーリンク
スポンサーリンク
SNSフォローボタン

フォローする

スポンサーリンク
スポンサーリンク