Datetimeフィールドを持つSQLテーブルがあります。問題のフィールドはnullでもかまいません。クエリがあり、結果をdatetimeフィールドで昇順にソートしたいのですが、datetimeフィールドが先頭ではなくリストの最後でnullになっている行が必要です。
それを達成するための簡単な方法はありますか?
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
(少し遅れましたが、これはまったく言及されていません)
DBMSを指定していません。
標準SQL(およびOracle、PostgreSQL、DB2、Firebird、Apache Derby、HSQLDB、H2などの最新のDBMS)では、NULLS LAST
またはNULLS FIRST
を指定できます。
最後にソートするにはNULLS LAST
を使います。
select *
from some_table
order by some_column DESC NULLS LAST
私はまたこれに遭遇したばかりで、MySQLとPostgreSQLでは、次のようなトリックを行っているようです。
ORDER BY date IS NULL, date DESC
order by coalesce(date-time-field,large date in future)
以下のように、組み込み関数を使用して、nullかどうかをチェックできます。私はそれをテストし、それはうまく機能します。
select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;
あなたのエンジンがORDER BY x IS NULL, x
またはORDER BY x NULLS LAST
を許可するのであればそれを使用してください。しかし、そうでない場合、これらは役に立ちます。
数値型でソートしている場合は、これを実行できます。(スキーマを 別の回答 から借用する)
SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;
Null以外の数値は0になり、nullは1になり、最後にnullがソートされます。
文字列に対してもこれを行うことができます。
SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName
'a'
> ''
のためです。
これはnullを許容するint型に強制し、上記のint型のメソッドを使用することで日付に対しても有効です。
SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate
(スキーマにHireDateがあるとしましょう。)
これらの方法は、すべてのタイプの "最大"値を考え出したり管理したり、データタイプ(および最大値)が変更された場合にクエリを修正しなければならないという問題を回避します加えて、それらはCASEよりずっと短いです。
注文列が数値の場合(ランクのように)、-1を掛けてから降順で注文できます。それはあなたが期待している順番を保ちますが、最後にNULLを置きます。
select *
from table
order by -rank desc
SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId, 99999);
このブログ記事 を参照してください。
Oracleでは、NULLS FIRST
またはNULLS LAST
を使用できます。NULL以外の値の前後にNULL値を返すように指定します。
ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }
例えば:
ORDER BY date DESC NULLS LAST
参照: http://docs.Oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html
NULL可能な日時フィールドのソートに関するバグの問題に優れた解決策を提供してくれてありがとうRedFilter。
プロジェクトにSQL Serverデータベースを使用しています。
Datetime NULL値を '1'に変更すると、datetimeデータ型列のソートに関する問題が解決されます。ただし、datetimeデータ型以外の列があると、処理できません。
Varcharカラムのソートを処理するために、カラムの値が 'Z'で始まっていないことがわかっていたので、 'ZZZZZZZ'を使用しました。期待通りに動作しました。
同じ行で、期待どおりにソートするために、int型およびその他のデータ型に最大値+1を使用しました。これも私が要求された結果を私に与えた。
ただし、データベースエンジン自体をもっと簡単にして、次のようなことができるようにするのが理想的です。
Order by Col1 Asc Nulls Last, Col2 Asc Nulls First
A_horse_with_no_nameによって提供される回答で述べたように。
order by -cast([nativeDateModify] as bigint) desc
"case"を使った解決策は一般的ですが、その場合はインデックスを使わないでください。
order by case when MyDate is null then 1 else 0 end, MyDate
私の場合は、パフォーマンスが必要でした。
SELECT smoneCol1,someCol2
FROM someSch.someTab
WHERE someCol2 = 2101 and ( someCol1 IS NULL )
UNION
SELECT smoneCol1,someCol2
FROM someSch.someTab
WHERE someCol2 = 2101 and ( someCol1 IS NOT NULL)
MariaDBを使用している場合は、 NULL値のドキュメント に次のように記載されています。
注文
NULL値を含む可能性のあるフィールドで並べ替えると、すべてのNULL値が最小値と見なされます。そのため、DESC順に並べると、NULLが最後に現れます。 NULLを強制的に最大値と見なすには、メインフィールドがNULLのときに、より高い値を持つ列をもう1つ追加します。例:
SELECT col1 FROM tab ORDER BY ISNULL(col1), col1;
最初にNULLを使用して降順に並べます。
SELECT col1 FROM tab ORDER BY IF(col1 IS NULL, 0, 1), col1 DESC;
すべてのNULL値も、DISTINCT句およびGROUP BY句の目的のためには同等と見なされます。
上記はNULL値で並べる2つの方法を示しています。これらをASCキーワードおよびDESCキーワードと組み合わせることもできます。たとえば、最初にNULL値を取得するもう1つの方法は次のようになります。
SELECT col1 FROM tab ORDER BY ISNULL(col1) DESC, col1;
-- ^^^^
NVL機能を使用する
select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))
これが 最も有名なDBMSでのNVLの代替 です