超メモ帳(Web式)@復活

小説書いたり、絵を描いたり、プログラムやったりするブログ。統失プログラマ。


SPONSORED LINK

MySQLのorder byで詳細に条件を指定して並べ替えたい場合。

f:id:yuki_2021:20180226120405j:plain:w300


仕事中で詰まったので調べた。結構、ありがちな処理なんだけど初めて知ったので、情報共有のためにエントリーにしておく。


MySQLで出力される結果を並び替える場合は「order by」を使うんだけど、これはascとdescで昇順と降順の並び替えしかできない。


例えば、給料の日割りと額で並び替えたいって場合は条件を複数並べればいい。

No 日割り 金額
1 月給 180000
2 時給 850
3 日給 8000
4 月給 150000


上記のテーブルがあるときならば下記になる。

select * from 給与明細 
order by 日割り desc, 金額 desc;
No 日割り 金額
1 月給 180000
4 月給 150000
3 日給 8000
2 時給 850


ちなみにorder byはint型のような数値にかぎらずvarchar型でもソートできる。日本語でも大丈夫。詳細はこちらでも参照してください。


blog.higty.xyz


で、本題なんだけど上記のテーブルで日割りをソートするときに、必ず日給を一番上に来るようにソートするにはどうすれば良いと思う?これ、結構悩んで詰まった。


こういう場合はCase文を使えば良いんである。

CASE
WHEN 条件1 THEN 処理
WHEN 条件2 THEN 処理
WHEN 条件3 THEN 処理

ELSE 処理
END

select * from 給与明細 
order by case 
when (日割り = '日給') then 100 
else 0 end desc, 日割り desc, 金額 desc;
No 日割り 金額
3 日給 8000
1 月給 180000
4 月給 150000
2 時給 850


MySQL:CASEを使ってレコードをソート(ORDER BY) | エンジニア足立のコーディング日記 - 株式会社ディープ


このSQL文では最初に日割りで日給に当てはまる行に100というパラメータを割り振ってそれ以外には0を割り振る。そしてorder byで並び替えた上で、他の行の並び替えをしている。order byにCase文を使うと条件を指定した柔軟な並び替えが可能になる。


Case文は他にもいろんなことに使える。例えば、県コードは、1:北海道、2:青森、・・・・・・ 47:沖縄というように振られているが、これを東北、関東、九州といった地方単位にまとめて、その単位で人口を集計したい、という場合。


通常ならば新しく地方コードのカラムを追加しなければならないんだけど、テーブルが冗長になる。これをSQL側で対応することができる。

SELECT  SUM(popularity), 
 CASE pre_name
 WHEN '徳島県' THEN '四国'
 WHEN '香川県' THEN '四国'
 WHEN '愛媛県' THEN '四国'
 WHEN '高知県' THEN '四国'
 WHEN '福岡県' THEN '九州'
 WHEN '佐賀県' THEN '九州'
 WHEN '長崎県' THEN '九州'
 WHEN '熊本県' THEN '九州'
 WHEN '大分県' THEN '九州'
 ELSE 'その他' END
 FROM Table_A
GROUP BY CASE pre_name
 WHEN '徳島県' THEN '四国'
 WHEN '香川県' THEN '四国'
 WHEN '愛媛県' THEN '四国'
 WHEN '高知県' THEN '四国'
 WHEN '福岡県' THEN '九州'
 WHEN '佐賀県' THEN '九州'
 WHEN '長崎県' THEN '九州'
 WHEN '熊本県' THEN '九州'
 WHEN '大分県' THEN '九州'
 ELSE 'その他' END;


CASE式のススメ


データの複雑な並び替えや変更を行わないといけないけど、データベースの構造には触れたくないシーンはありがちだ。そういう時にはCase文を使えばなんとかなるかもしれない。


MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.6.5.1 CASE 構文

プライバシーポリシー免責事項