SQL Server ORDER BY日期和空值最后

UpH*_*lix 71 t-sql sql-server sql-server-2005

我想按日期订购.我希望最新的日期出现在第一位.这很容易,但有许多记录是空的,而且这些记录在任何有日期的记录之前.

我尝试了一些没有成功的事情:

ORDER BY ISNULL(Next_Contact_Date, 0)

ORDER BY ISNULL(Next_Contact_Date, 999999999)

ORDER BY coalesce(Next_Contact_Date, 99/99/9999)
Run Code Online (Sandbox Code Playgroud)

我如何按日期订购并让空值最后出现?数据类型是smalldatetime.

Mar*_*ith 100

smalldatetime 范围可达2079年6月6日,因此您可以使用

ORDER BY ISNULL(Next_Contact_Date, '2079-06-05T23:59:00')
Run Code Online (Sandbox Code Playgroud)

如果没有合法记录将具有该日期.

如果这不是一个假设,你想要依赖更强大的选项是在两列上进行排序.

ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date
Run Code Online (Sandbox Code Playgroud)

上述两个建议都无法使用索引来避免排序,而是提供类似的计划.

在此输入图像描述

如果存在这样的索引,则另一种可能性是

SELECT 1 AS Grp, Next_Contact_Date 
FROM T 
WHERE Next_Contact_Date IS NOT NULL
UNION ALL
SELECT 2 AS Grp, Next_Contact_Date 
FROM T 
WHERE Next_Contact_Date IS NULL
ORDER BY Grp, Next_Contact_Date
Run Code Online (Sandbox Code Playgroud)

计划


小智 24

据伊茨克奔甘,作者T-SQL基础对MS SQL Server 2012中,"默认情况下,SQL Server的排序NULL之前非标记NULL值.要获得NULL标记进行排序最后,你可以使用一个CASE返回表达1当" Next_Contact_Date列是NULL,"和0时,它不是NULL.非NULL马克得到0从表达式后面;因此,它们排序之前NULL.标记(这得到1)本CASE表达被用作所述第一排序栏." 该Next_Contact_Date列"应该被指定为第二排序列.这样一来,非NULL标志着排序正确三者结合起来." 以下是MS SQL Server 2012(和SQL Server 2014)示例的解决方案查询:

ORDER BY 
   CASE 
        WHEN Next_Contact_Date IS NULL THEN 1
        ELSE 0
   END, Next_Contact_Date;
Run Code Online (Sandbox Code Playgroud)

使用IIF语法的等效代码:

ORDER BY 
   IIF(Next_Contact_Date IS NULL, 1, 0),
   Next_Contact_Date;
Run Code Online (Sandbox Code Playgroud)