[MySQL] ORDER BYでNULLや0を最後に並べる方法

データベース データベース

MySQLで通常のソートでは0やNULLは先頭に並べられてしまいます。
これを回避して、NULLや0はソートの最後にする方法を紹介します。
LaravelのEloquentでの記載方法も紹介します。

テスト用のテーブルとレコードを作成するSQL

CREATE TABLE tests (`id` INT PRIMARY KEY AUTO_INCREMENT,`rank` INT);
INSERT INTO tests (`rank`) VALUES (NULL),(0),(1),(2),(3);

通常の動作

SELECT * FROM tests
ORDER BY
  `rank` ASC;
+----+------+
| id | rank |
+----+------+
|  1 | NULL |
|  2 |    0 |
|  3 |    1 |
|  4 |    2 |
|  5 |    3 |
+----+------+

NULLを最後に並べたい場合

SELECT * FROM tests
ORDER BY
  `rank` IS NULL ASC, -- 追加
  `rank` ASC;
+----+------+
| id | rank |
+----+------+
|  2 |    0 |
|  3 |    1 |
|  4 |    2 |
|  5 |    3 |
|  1 | NULL |
+----+------+

LaravelのEloquentでのコードはこのようになります。

Tests::orderByRaw('rank IS NULL ASC')
    ->orderBy('rank', 'ASC')
    ->get();

NULLと0を最後に並べたい場合

SELECT * FROM tests
ORDER BY
  `rank` IS NULL ASC, -- 追加
  `rank` = 0 ASC,     -- 追加
  `rank` ASC;
+----+------+
| id | rank |
+----+------+
|  3 |    1 |
|  4 |    2 |
|  5 |    3 |
|  2 |    0 |
|  1 | NULL |
+----+------+

NULLは最後にして降順に並べたい場合

SELECT * FROM tests
ORDER BY
  `rank` IS NULL ASC,
  `rank` DESC; -- DESCにする
+----+------+
| id | rank |
+----+------+
|  5 |    3 |
|  4 |    2 |
|  3 |    1 |
|  2 |    0 |
|  1 | NULL |
+----+------+

おまけ:うまくいかない場合

ORDER BYの順序が異なるとうまくいかないです。

SELECT * FROM tests
ORDER BY
  `rank` = 0 ASC,
  `rank` IS NULL ASC, -- 0とNULLの順番を逆にした
  `rank` ASC;
+----+------+
| id | rank |
+----+------+
|  1 | NULL |
|  3 |    1 |
|  4 |    2 |
|  5 |    3 |
|  2 |    0 |
+----+------+

コメント

タイトルとURLをコピーしました