今は2017年ですが、NULL
sを優先すべきかどうかについてはまだコンセンサスが得られていません。あなたがそれについて明確にしないと、あなたの結果はDBMSによって異なります。
標準では、NULL以外の値と比較してNULLを並べ替える方法を指定していません。ただし、2つのNULLは同じ順序であると見なされ、NULLはすべてのNULL以外の値の上または下に並べ替える必要があります。
ソース、ほとんどのDBMSの比較
この問題を説明するために、Rails開発に関して最も人気のあるいくつかのケースのリストをまとめました。
PostgreSQL
NULL
sの値が最も高くなります。
デフォルトでは、null値はnull以外の値よりも大きいかのようにソートされます。
出典:PostgreSQLドキュメント
MySQL
NULL
sの値が最も低くなります。
ORDER BYを実行する場合、ORDER BY ... ASCを実行すると最初にNULL値が表示され、ORDER BY ... DESCを実行すると最後にNULL値が表示されます。
出典:MySQLドキュメント
SQLite
NULL
sの値が最も低くなります。
NULL値の行は、通常の値の行よりも昇順で高く、降順では逆になります。
ソース
解決
残念ながら、Rails自体はまだその解決策を提供していません。
PostgreSQL固有
PostgreSQLの場合、非常に直感的に使用できます。
Photo.order('collection_id DESC NULLS LAST') # NULLs come last
MySQL固有
MySQLの場合、マイナス記号を前もって置くことができますが、この機能は文書化されていないようです。数値だけでなく、日付でも機能するように見えます。
Photo.order('-collection_id DESC') # NULLs come last
PostgreSQLおよびMySQL固有
それらの両方をカバーするために、これは機能するように見えます:
Photo.order('collection_id IS NULL, collection_id DESC') # NULLs come last
それでも、これはSQLiteでは機能しません。
ユニバーサルソリューション
すべてのDBMSにクロスサポートを提供するにCASE
は、@ PhilITによってすでに提案されている、を使用してクエリを作成する必要があります。
Photo.order('CASE WHEN collection_id IS NULL THEN 1 ELSE 0 END, collection_id')
これは、最初に各レコードをCASE
結果(デフォルトでは昇順、つまりNULL
値が最後の値になる)で最初にソートし、次に。でソートすることを意味しますcalculation_id
。