Sql server SQL Server按日期排序,最后为空
我想按日期订货。我想把最近的约会放在第一位。这很简单,但是有许多记录是空的,并且这些记录出现在任何有日期的记录之前 我尝试了几件事,但都没有成功:Sql server SQL Server按日期排序,最后为空,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,我想按日期订货。我想把最近的约会放在第一位。这很简单,但是有许多记录是空的,并且这些记录出现在任何有日期的记录之前 我尝试了几件事,但都没有成功: ORDER BY ISNULL(Next_Contact_Date, 0) ORDER BY ISNULL(Next_Contact_Date, 999999999) ORDER BY coalesce(Next_Contact_Date, 99/99/9999) 我怎样才能按日期订购,最后才有空的呢?数据类型为smalldatetimesma
ORDER BY ISNULL(Next_Contact_Date, 0)
ORDER BY ISNULL(Next_Contact_Date, 999999999)
ORDER BY coalesce(Next_Contact_Date, 99/99/9999)
我怎样才能按日期订购,最后才有空的呢?数据类型为
smalldatetime
smalldatetime
的范围为2079年6月6日,因此您可以使用
ORDER BY ISNULL(Next_Contact_Date, '2079-06-05T23:59:00')
如果没有合法的记录,将有该日期
如果这不是一个假设,那么依赖一个更健壮的选项是对两列进行排序
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date
然而,上述两种建议都无法使用索引来避免排序,并给出类似的计划
如果存在这样一个指数,另一种可能性是
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
如果SQL不支持
NULL FIRST
或NULL LAST
,最简单的方法是使用值is NULL
表达式:
ORDER BY Next_Contact_Date IS NULL, Next_Contact_Date
将空值放在末尾(nulls LAST
)或
把空的放在前面。这不需要知道列的类型,并且比CASE
表达式更易于阅读
编辑:唉,虽然这在其他SQL实现(如PostgreSQL和MySQL)中有效,但在MS SQL Server中不起作用。我没有SQL Server可供测试,依赖于Microsoft的文档和其他SQL实现的测试。根据微软的说法,值是空的
,应该像其他表达式一样可用。和采用表达式的任何其他语句一样,orderby
。但它实际上不起作用
因此,SQL Server的最佳解决方案似乎是
CASE
表达式。有点晚了,但可能有人发现它很有用
对我来说,由于表扫描,ISNULL是不可能的。UNIONALL需要我重复一个复杂的查询,由于我只选择了最上面的X,所以效率不高
如果能够更改表格设计,则可以:
CREATE TRIGGER FILL_SORTABLE_DATE ON YOUR_TABLE AFTER INSERT,UPDATE AS
BEGIN
SET NOCOUNT ON;
IF (update(Next_Contact_Date)) BEGIN
UPDATE YOUR_TABLE SET Next_Contact_Date_Sort=IIF(YOUR_TABLE.Next_Contact_Date IS NULL, 99/99/9999, YOUR_TABLE.Next_Contact_Date_Sort) FROM inserted i WHERE YOUR_TABLE.key1=i.key1 AND YOUR_TABLE.key2=i.key2
END
END
如有必要,使用desc并乘以-1。最后为空的升序整数排序示例:
select *
from
(select null v union all select 1 v union all select 2 v) t
order by -t.v desc
根据MS SQL Server 2012 T-SQL基础知识的作者伊兹克·本·甘的说法,“默认情况下,SQL Server在非NULL值之前排序NULL标记。要获得NULL标记以进行最后排序,可以使用大小写表达式,当Next\u Contact\u Date列为NULL,“当它不为NULL时为0。非NULL标记从表达式返回0;因此,它们在NULL标记(得到1)之前排序。此CASE表达式用作第一个排序列。”应将“下一个联系人日期”列指定为第二个排序列。这样,非NULL会正确标记它们之间的排序。以下是针对MS SQL Server 2012(和SQL Server 2014)示例的解决方案查询: 使用IIF语法的等效代码:
ORDER BY
IIF(Next_Contact_Date IS NULL, 1, 0),
Next_Contact_Date;
我知道这很古老,但这对我来说很有用
Order by Isnull(Date,'12/31/9999')
排序顺序是否需要升序,但结尾为空?你的桌子上会有未来的日期吗?@AllenG,是的,从过去到未来,以过去为先,以此类推。所以,是的,上升。是的,未来的日期将是大多数日期。这是无效的SQL Server语法。对此,我深表歉意。根据Microsoft文档,它应该是有效的,并且适用于其他SQL,但MS实际上不允许。性能方面,这听起来很糟糕,因为您正在执行2排序标准在您链接的Microsoft文档中,我了解到值为NULL不是一个表达式,而是一个谓词。根据微软的说法,谓词是一个表达式。如果
Next\u Contact\u Date
为null,则这就是抛出错误的前三个单词不允许从数据类型Date显式转换为bigint。
此外,为了补充答案,如果在null周围切换IIF的1和0,则将转到顶部。如果您希望通过将元组放在表的顶部来获得一个单独的元组,则此技巧也适用于VARCHAR
字段(例如,orderbyisnull(my_VARCHAR,'ZZZZZZ')
),并且非常有用,特别是在使用groupby时以某种方式获取订单。分组集
。谢谢你发布这篇文章。为什么我们不能使用order by desc将空值放在底部?还有,为什么我们要将null映射到1?我不认为这对日期之类的变量有效。。
ORDER BY
CASE
WHEN Next_Contact_Date IS NULL THEN 1
ELSE 0
END, Next_Contact_Date;
ORDER BY
IIF(Next_Contact_Date IS NULL, 1, 0),
Next_Contact_Date;
Order by Isnull(Date,'12/31/9999')