ねこじゃすり
猫を魅了する魔法の装備品!
ペヤング ソースやきそば 120g×18個
とりあえず保存食として買っておけば間違いなし!
モンスターエナジー 355ml×24本 [エナジードリンク]
脳を活性化させるにはこれ!
ドラゴンクエスト メタリックモンスターズギャラリー メタルキング
みんな大好き経験値の塊をデスクに常備しておこう!
BANDAI SPIRITS ULTIMAGEAR 遊戯王 千年パズル 1/1スケール
もう一人の僕を呼び覚ませ!!
MOFT X 【新型 ミニマム版】 iPhone対応 スマホスタンド
Amazon一番人気のスマホスタンド!カード類も収納出来てかさ張らないのでオススメです!
サンディスク microSD 128GB
スマホからSwitchまで使える大容量MicroSDカード!
スポンサーリンク
目次
MySQLのNULLに対するORDER BYの取り扱いについて
MySQLにて、NULL
が許容されたカラムに対してORDER BY
をかける際にはちょっと注意した方が良いです。
何も気にせずにORDER BY
をかけると想定と違う挙動になる場合もあるので、MySQLのNULL
に対する挙動の整理とNULL
に対する優先度を制御する方法をご紹介しようと思います。
NULLの取り扱いについてのおさらい
前提
今回は以下のテーブルを使って試しています。
1 2 3 4 5 6 7 8 |
CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(255) NOT NULL COMMENT '名前', `age` varchar(255) COMMENT '年齢', `priority` int(10) COMMENT '優先度', `created_at` datetime NOT NULL COMMENT '登録日', PRIMARY KEY (`id`) ) COMMENT = '会員情報'; |
投入データはこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
INSERT INTO `users` VALUES ( 1, 'Taro', -- name 20, -- age 2, -- priority NOW()-- created_at ),( 2, 'Jiro', -- name 18, -- age NULL, -- priority NOW()-- created_at ),( 3, 'Saburo', -- name 185, -- age 1, -- priority NOW()-- created_at ); |
通常のORDER BY
それでは、priority
カラムを軸にORDER BY
して見ます。
ASC(昇順)の場合
まずはASC
から確認して見ましょう。
1 2 3 4 5 6 7 8 |
+----+--------+------+----------+---------------------+ | id | name | age | priority | created_at | +----+--------+------+----------+---------------------+ | 2 | Jiro | 18 | NULL | 2020-03-30 13:46:03 | | 3 | Saburo | 185 | 1 | 2020-03-30 13:46:03 | | 1 | Taro | 20 | 2 | 2020-03-30 13:46:03 | +----+--------+------+----------+---------------------+ 3 rows in set (0.00 sec) |
結果としてはNULL
が最大値として判定され、そのあとに値の昇順(0,1,2...
)が判定されています。
DESC(降順)の場合
次にDESC
で確認して見ましょう。
1 2 3 4 5 6 7 8 |
+----+--------+------+----------+---------------------+ | id | name | age | priority | created_at | +----+--------+------+----------+---------------------+ | 1 | Taro | 20 | 2 | 2020-03-30 13:46:03 | | 3 | Saburo | 185 | 1 | 2020-03-30 13:46:03 | | 2 | Jiro | 18 | NULL | 2020-03-30 13:46:03 | +----+--------+------+----------+---------------------+ 3 rows in set (0.00 sec) |
結果としては値の降順(100,99,98...
)が判定されNULL
が最小値
となっています。
NULLの優先度を制御する方法
ORDER BY句の先頭にIS NULLを追加
上記で紹介したようなシンプルなORDER BY
とは違う順序制御をしたい場合は、ORDER BY
句の先頭にORDER BY {対象項目} IS NULL {ASC or DESC},{対象項目}
とするだけで制御が可能になります。
NULLの優先度を最低、値を昇順にしたい場合
以下のSQLで実現可能です。
1 2 3 4 5 6 7 8 |
+----+--------+------+----------+---------------------+ | id | name | age | priority | created_at | +----+--------+------+----------+---------------------+ | 3 | Saburo | 185 | 1 | 2020-03-30 13:46:03 | | 1 | Taro | 20 | 2 | 2020-03-30 13:46:03 | | 2 | Jiro | 18 | NULL | 2020-03-30 13:46:03 | +----+--------+------+----------+---------------------+ 3 rows in set (0.00 sec) |
期待通りの並び順になりましたね♪
上記の構文を解説すると、まず値がNULL
かどうかの判定を行いNULL
じゃない場合をFALSE(=0)
と判定し、その値でASC
をかけることにより値が登録されているレコードを優先的に取得し、そのあとに値がNULL
の場合のレコードを昇順で取得するようにしています。
NULLの優先度を最高、値を降順にしたい場合
以下のSQLで実現可能です。
1 2 3 4 5 6 7 8 |
+----+--------+------+----------+---------------------+ | id | name | age | priority | created_at | +----+--------+------+----------+---------------------+ | 2 | Jiro | 18 | NULL | 2020-03-30 13:46:03 | | 1 | Taro | 20 | 2 | 2020-03-30 13:46:03 | | 3 | Saburo | 185 | 1 | 2020-03-30 13:46:03 | +----+--------+------+----------+---------------------+ 3 rows in set (0.00 sec) |
こちらも期待通りの結果になりました。
上記の構文を解説すると、まず値がNULL
かどうかの判定を行いNULL
じゃない場合をFALSE(=0)
と判定し、その値でDESC
をかけることにより値がNULL
の場合のレコードを優先的に取得し、そのあとに値が登録されているレコードを降順で取得するようにしています。
終わりに
以上のようにちょっと取り扱いが難しいMySQLのNULL
に対するORDER BY
テクニックでした。
今回ご紹介した4パターンを覚えておけば、NULL
が混在したカラムに対するORDER BY
は網羅出来ると思うので、お困りの方はぜひ試して見てください♪