[order by null 最後]
数値カラムをソートするとき、「null,1,2,3...」の順になる。
ステータスを表すカラムだったりすると、1,2,3をまず表示してnullは後にしたいとか制御が必要になったりする。
そういうときに
order by case when b_clm is null then 10 else 0 end asc,
b_clm asc
のように二段階ソートするとnullを最大として扱かったりできる。
表
テーブルA
a_id | a_clm1 | a_clm2 |
---|---|---|
1 | 1 | 3 |
2 | 1 | 3 |
3 | 2 | 4 |
テーブルB
b_id | b_a_id |
---|---|
1 | 1 |
2 | 2 |
テーブルC
c_id | c_a_id |
---|---|
1 | 1 |
2 | 2 |
こんな感じのときに、AとBを結合して、Cはサブクエリで取るとする。
SQLServerでnullの位置を制御
fromとjoinに入っているカラムはorder byのなかでcase whenできる。
SQLServerが試せるところにないのであまり確認できないのだけど、次のような感じだった。
A.
select a_id
,(select top 1 c_clm from tablec where c_a_id = a_id order by c_id desc) as c_clm
from tablea
left join tableb on b_a_id=a_id
order by
case when b_clm is null then 10 else 0 end asc
,b_clm asc
これはb_clmがfromとjoinで指定したテーブルのカラムなのでいける。
B.
select a_id
,(select top 1 c_clm from tablec where c_a_id = a_id order by c_id desc) as c_clm
from tablea
left join tableb on b_a_id=a_id
order by
case when c_clm is null then 10 else 0 end asc
,c_clm asc
これはc_clmがfromとjoinに入ってない、サブクエリのカラムなので「c_clmは無効です」とか言われる。
order by c_clm asc
単体はいけるんだからcase whenもいけていいと思うんだけど。
B'.
それでこうやった。
select a_id
,(select top 1 (10 - c_clm) from tablec where c_a_id = a_id order by c_id desc) as c_clm_od
from tablea
left join tableb on b_a_id=a_id
order by c_clm_od asc
二段階のorder byは諦めて(しかもサブクエリでのCASE WHENも使えなかった)、select時に大小関係が逆になるように10-c_clmとしてそれでソートするようにした。
こうやってみると二段階order byよりこちらのほうがシンプルな感じがする。別に10から引かなくても普通に(-c_clm)でよかったかも。
これが手元のMySQLで試したら両方行けた。
今検索したら、2件目のリンクによるとこれでもいけた。こっちのほうがシンプルだった。
order by c_clm is null asc
SQLServerで使えるんだろうか。
参考
[SQLServer][SQL] Order by で NULLを最後に持ってくる
【SQL】ORDER BY で NULL を最後にする場合の注意点