MySQL Orderby a number、nulls last


279

現在、私はステートメントで非常に基本的なOrderByを実行しています。

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC

これの問題は、「位置」のNULLエントリが0として扱われることです。したがって、位置がNULLのすべてのエントリは、1,2,3,4の前に表示されます。例えば:

NULL, NULL, NULL, 1, 2, 3, 4

次の順序を実現する方法はありますか?

1, 2, 3, 4, NULL, NULL, NULL.

8
user1052645の回答を再検討する必要があります。それはより単純で、最大値の知識を必要とせず、より高速である可能性があります(式の評価は関数呼び出しよりも高速であると想定しています)。
Steve Clay、

回答:


566

MySQLには、nullを最後にソートするための文書化されていない構文があります。列名の前にマイナス記号(-)を置き、ASCをDESCに切り替えます。

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC, id DESC

これは基本的にposition DESCNULL値を最後に配置することの逆ですが、それ以外はと同じposition ASCです。

良いリファレンスはこちらhttp://troels.arvin.dk/db/rdbms#select-order_by


79
ドキュメント化されていないわけで- col_nameはなく0 - col_name、ORDER BY句が受け入れる式()です。もちろん、これは数値列に対してのみ機能します。
Steve Clay、

7
良いですね。以下のための作品datetimeあまりにも列!(MySQL 5.5)。私は(私がチェックするのが面倒です)それはすべての数値のような列(タイムスタンプ、浮動小数点...)で機能すると思います。
マーティン

6
@koral:これは順序を逆にする単純な(そして便利な)数式であり、言語自体が劇的に変化しない限り削除されません。
ベル

11
コメントが示唆するように、それは数値、日付、時刻の列で機能しますか?しかし、varcharはどうですか?varcharにも適用できますか?varcharフィールドに適用してみましたが、ASCまたはDESCを使用した場合と順序が異なっているようです。
Sumit Desai 2014

9
これにより、列による順序での可能なインデックスの使用が妨げられませんか?
タルシス

305

私はこれが大部分の良い解決策であることがわかりました:

SELECT * FROM table ORDER BY ISNULL(field), field ASC;

6
:作品によって順序を再定義せずにSELECT * FROM table ORDER BY ISNULL(field) ASC;(MySQLの5.5)
Marçalフアン

5
これはより良いソリューションです。
Rok Kralj

4
承認されたソリューションは、postgresql 9.3のTIMESTAMPでは機能しません。このソリューションは...
kalu 2014

2
厄介なことに、isnull(field)をorder by句に追加すると(制限を使用する場合)、MySQLはフィールドのインデックスを使用しません。
バリーケリー

3
@kalu:PostgreSQLでは、NULL値は最後に昇順で(そして最初に降順で)ソートされます。そして、あなたはむしろ標準のSQL句をNULLS LASTNULLS FIRST使用したいでしょう| ここの回避策の代わりにそれを反転します。
Erwin Brandstetter 2016年

23

何かのようなもの

SELECT * FROM tablename where visible=1 ORDER BY COALESCE(position, 999999999) ASC, id DESC

999999999をフィールドの最大値に置き換えます


3
このソリューションは壊れやすく、断続的なバグにつながる可能性があります
Dmitry Bogdanovich

20

最後のNULL

SELECT * FROM table_name ORDER BY id IS NULL, id ASC

4

NULLのインスタンスを別の値に交換して、最初(0または-1など)または最後(大きな数または文字)にソートできます...

SELECT field1, IF(field2 IS NULL, 9999, field2) as ordered_field2
  FROM tablename
 WHERE visible = 1
 ORDER BY ordered_field2 ASC, id DESC

ORDER BYで参照されるインデックスはSELECTステートメントの値を置き換えることによる影響を受けないため、これで問題が解決されず、順序が修正されません。また、IF関数の使用と機能的に同等のCOALESCE関数も確認してください。
定義

IFステートメントのエイリアスを適切に設定すると、行は期待どおりに並べられます。私は自分の例を修正しました。
ラングドン

4

このクエリを使用してみてください:

SELECT * FROM tablename
WHERE visible=1 
ORDER BY 
CASE WHEN position IS NULL THEN 1 ELSE 0 END ASC,id DESC

ケースは必要ありません。IS NULLは、式がNULLの場合に1を返します。残響の答えを見てください。
contactmatt 2018

3

次のステートメントでNULLを合体できますORDER BY

select * from tablename
where <conditions>
order by
    coalesce(position, 0) ASC, 
    id DESC

NULLを下からソートする場合は、を試してくださいcoalesce(position, 100000)。(2番目の数値positionを、データベース内の他のすべての数値よりも大きくします。)


3
SELECT * FROM tablename WHERE visible=1 ORDER BY CASE WHEN `position` = 0 THEN 'a' END , position ASC

6
なぜOPはこれを試すべきなのか?良い答えには常に、何が行われたか、なぜOPがそのように行われたのかについての説明があります。OPだけでなく、この質問を見つけて回答を読んでいる可能性があるSOへの将来の訪問者にとってもです。
RiggsFolly 2017

2

以下のためにDATE列にあなたが使用することができます。


NULLS最後:

ORDER BY IFNULL(`myDate`, '9999-12-31') ASC

ブランクは最後:

ORDER BY IF(`myDate` = '', '9999-12-31', `myDate`) ASC

1

次の結果を達成するために:

1, 2, 3, 4, NULL, NULL, NULL.

構文を使用し、-(minus sign)フィールド名の前に配置して、order_typeの逆を使用します(ASC順による順序が必要な場合はDESCを使用するか、DESC順序が必要な場合はASCを使用します)

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC


1

これは正常に動作しています:

SELECT * FROM tablename ORDER BY position = 0, position ASC;

position
1 
2
3
0
0

-8

NULLS LASTで注文してみませんか?

SELECT * 
FROM tablename
WHERE visible = 1 
ORDER BY position ASC NULLS LAST, id DESC 

NULLS LAST-どのバージョンのMySQLが導入されましたか?
crmpicco

2
@パニック、あなたは(MS)SQLサーバーを意味しますか?
d -_- b

1
この回答はMySQLには適用されません
PeppyHeppy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.