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

时间:2009-09-30 14:56:50

标签: sql sorting sql-order-by

我有一个带有日期时间字段的SQL表。有问题的字段可以为null。我有一个查询,我希望结果按日期时间字段按升序排序,但是我想要在列表末尾的datetime字段为空的行,而不是在开头。

有没有一种简单的方法可以实现这一目标?

14 个答案:

答案 0 :(得分:358)

select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate

答案 1 :(得分:142)

(“有点”迟到了,但根本没有提到过)

您没有指定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

答案 2 :(得分:32)

我也偶然发现了这一点,以下似乎对我有所帮助,在MySQL和PostgreSQL上:

ORDER BY date IS NULL, date DESC

https://stackoverflow.com/a/7055259/496209

处找到

答案 3 :(得分:14)

order by coalesce(date-time-field,large date in future)

答案 4 :(得分:13)

您可以使用内置函数检查null或not null,如下所示。我测试它并且工作正常。

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

答案 5 :(得分:9)

如果您的引擎允许ORDER BY x IS NULL, xORDER BY x NULLS LAST使用该引擎。但如果不是这些可能会有所帮助:

如果您按数字类型排序,则可以执行以下操作:(从another answer借用架构。)

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

result showing sorted by DepartmentId with nulls last

任何非空数字都变为0,空值变为1,最后对空值进行排序。

您也可以为字符串执行此操作:

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

result showing sorted by LastName with nulls last

因为'a'> ''

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

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

(让我假装架构有HireDate。)

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

答案 6 :(得分:6)

当您的订单栏是数字(如排名)时,您可以将其乘以-1然后按顺序递减。它会保留您要求的顺序,但最后会保留NULL。

select *
from table
order by -rank desc

答案 7 :(得分:4)

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

请参阅this blog post

答案 8 :(得分:3)

感谢RedFilter为排序可为空的日期时间字段提供了出色的解决方案。

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

将datetime null值更改为“1”确实解决了datetime数据类型列的排序问题。但是,如果我们的列不是datetime数据类型,那么它就无法处理。

为了处理varchar列排序,我尝试使用'ZZZZZZZ',因为我知道列没有以'Z'开头的值。它按预期工作。

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

然而,在数据库引擎本身中获得更容易的东西总是理想的,这可以做类似的事情:

Order by Col1 Asc Nulls Last, Col2 Asc Nulls First 

如a_horse_with_no_name提供的答案所述。

答案 9 :(得分:3)

在Oracle中,您可以使用bin/console h:d:f:lNULLS FIRST:指定应在非NULL值之前/之后返回NULL值:

NULLS LAST

例如:

ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }

参考:http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html

答案 10 :(得分:1)

order by -cast([nativeDateModify] as bigint) desc

答案 11 :(得分:1)

使用“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)  

答案 12 :(得分:0)

USE NVL功能

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

此处the alternative of NVL in most famous DBMS

答案 13 :(得分:0)

如果您使用的是MariaDB,他们会在NULL Values documentation中提及以下内容。

  

Ordering

     

当您按可能包含NULL值的字段排序时,所有NULL均为   被认为具有最低的价值。因此,按DESC顺序订购将看到   空值最后出现。要强制将NULL视为最高值,可以   当主字段为NULL时,添加另一个具有较高值的​​列。   示例:

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;
--                                         ^^^^