SQL如何使空值在升序排序时排在最后

我有一个带有datetime字段的SQL表。所讨论的字段可以为空。我有一个查询,我想要的结果排序由datetime字段上升,但我想要的行,其中的datetime字段是空在列表的结束,而不是在开始。

有什么简单的方法可以做到吗?

325902 次浏览
order by coalesce(date-time-field,large date in future)
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate

您可以使用内置函数检查null或非null,如下所示。我测试了它,它的工作良好。

select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;

(“有点”晚了,但这一点根本没有被提及)

您没有指定您的DBMS。

在标准SQL(以及大多数现代DBMS,如Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB和H2)中,您可以指定NULLS LASTNULLS FIRST:

使用NULLS LAST将它们排序到最后:

select *
from some_table
order by some_column DESC NULLS LAST

我也偶然发现了这一点,以下似乎为我做的伎俩,在MySQL和PostgreSQL:

ORDER BY date IS NULL, date DESC

如在https://stackoverflow.com/a/7055259/496209找到的

感谢RedFilter为排序空datetime字段的bug问题提供了出色的解决方案。

我使用SQL Server数据库为我的项目。

将datetime空值更改为“1”确实解决了对datetime数据类型列进行排序的问题。但是,如果列的数据类型不是datetime,则处理失败。

为了处理varchar列排序,我尝试使用'ZZZZZZZ',因为我知道列没有以'Z'开头的值。正如预期的那样。

在同一行中,我对int和其他数据类型使用max values +1来获得预期的排序。这也给了我所需要的结果。

然而,在数据库引擎本身中获得一些更简单的东西总是理想的,可以做一些像这样的事情:

Order by Col1 Asc Nulls Last, Col2 Asc Nulls First

正如a_horis_with_no_name提供的答案中提到的。

SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId, 99999);

看到这篇博文

.

使用NVL函数

  select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))

这是在大多数著名的DBMS中,它是NVL的替代品

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)

在Oracle中,你可以使用NULLS FIRSTNULLS 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

如果你的引擎允许ORDER BY x IS NULL, xORDER BY x NULLS LAST使用它。但如果没有,下面这些可能会有所帮助:

如果你是按数字类型排序,你可以这样做:(借用另一个答案的模式。)

SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;

result shows sorted by DepartmentId with nulls last

任何非null数都变成0,nulls变成1,最后对null进行排序,因为0 <1.

你也可以对字符串这样做:

SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName

result显示sorted by LastName with nulls last

任何非空字符串都变成'', null变成'a',最后对null排序,因为'' <'a'

这甚至可以通过将date强制为可空int并使用上面的方法来处理int:

SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate

(让我们假设模式具有HireDate。)

这些方法避免了必须提出或管理“最大值”的问题。如果数据类型(和最大值)发生变化(其他ISNULL解决方案都会遇到这两个问题),则修复查询。另外,它们比CASE要短得多。

当你的排序列是数字(像一个秩),你可以乘以-1,然后按顺序降序。它将保持您所期望的顺序,但将NULL放在最后。

select *
from table
order by -rank desc

如果你使用MariaDB,他们在NULL值中提到了以下内容 文档< / > . < / p >

排序 .

当您根据可能包含NULL值的字段进行排序时,任何NULL都是 最低的:被认为具有最低价值的在DESC中排序会看到 空值最后出现。要强制将null视为最大值,可以这样做 当主字段为NULL时,添加另一个具有更高值的列。 例子:< / p >

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值排序的方法,您可以将它们与 ASC和DESC关键字。例如,另一种获取NULL值的方法 第一个是:

SELECT col1 FROM tab ORDER BY ISNULL(col1) DESC, col1;
--                                         ^^^^