【问题标题】:T-SQL: Need a way to sort NULLs to top of a resultsetT-SQL:需要一种将 NULL 排序到结果集顶部的方法
【发布时间】:2014-05-16 16:31:56
【问题描述】:

场景:

我有一个简单的SELECT 查询,它从单个表中检索数据,按日期字段排序(此处的日期字段表示类似于“结束日期”)。应用逻辑是,如果这个“结束日期”为空,那么记录表示当前事件。现在,这些记录显示在按此结束日期排序的列表中,以便最新的记录显示在顶部。

显然,由于 NULL 日期记录被应用程序视为“当前”,因此它们需要位于此记录列表的顶部。如何让 SQL Server 2012 将它们排序到列表顶部?注意 -- 您可以在 ORDER BY 中使用伪(虚拟)值,但不能在 SELECT 部分选择此伪值。

这是我当前的查询(它不处理 NULL,“ContractEndDate”是我们感兴趣的日期字段):

SELECT 
    [Id], [UserName], [ContractEndDate] 
FROM 
    [UserContracts] 
ORDER BY 
    [ContractEndDate] DESC

任何指针都会很有用。

【问题讨论】:

  • 当您使用Order By 作为日期列时,NULL 的值无论如何都会排在最前面?那么这里有什么问题
  • 它没有那样做......这就是问题所在。在我的调试表中,我有三行,其中 2 个日期值为 NULL,第三行是 2013 年 1 月 1 日。期望看到 NULL,NULL 1-1-2013。但是当我运行上面的代码时,我看到 2013 年 1 月 1 日,NULL,NULL。那不是我想要的。

标签: sql sql-server sorting date


【解决方案1】:

按以下条件添加主要订单:

order by case when ContractEndDate is null then 0 else 1 end, ContractEndDate

【讨论】:

  • 我认为这是最好的答案,因为它非常明确地说空值是第一位的。
【解决方案2】:
     SELECT Id, UserName, ISNULL(ContractEndDate,GETDATE()) 
     FROM UserContracts 
     ORDER BY ISNULL(ContractEndDate,GETDATE()) DESC

【讨论】:

  • 谢谢。这也符合我得到的离线提示。
【解决方案3】:

您可以创建一个动态订单列并根据该列进行排序,然后按日期进行排序

;with CTE as (Select Id,Dt, (Case when Dt IS null then 0 else 1 end) OrderId
from Temp)

Select *
FRom CTE
Order by OrderId, Dt

这是小提琴sample

【讨论】:

  • 有点复杂。得到一个离线提示:ISNULL([ContractEndDate], GETDATE())。那工作得很好。您的解决方案也有效,因此请投票 :-)
  • @SujaySarma:虽然当日期为空时你不需要选择默认日期:)
  • ISNULL 在 ORDER BY 中而不在 SELECT 中。像这样:SELECT Id, UserName, ContractEndDate FROM UserContracts ORDER BY ISNULL(ContractEndDate,GETDATE()) DESC
【解决方案4】:

为简单起见,我们可以取一个伪列,即这里的 CASE 语句,并按此伪列排序。

SELECT 
[Id], [UserName], [ContractEndDate] 
FROM 
[UserContracts] 
ORDER BY 
(CASE WHEN [ContractEndDate] IS NULL THEN 0 ELSE 1 END), [ContractEndDate]    
DESC

【讨论】:

  • 答案仅由代码组成,没有解释为什么这样可以解决问题,可能会在审核过程中被删除。为防止出现这种情况,请说明为什么以及如何解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多