Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server按日期排序,最后为空_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

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,所以效率不高

如果能够更改表格设计,则可以:

  • 添加另一个字段,仅用于排序,例如下一个\u联系人\u日期\u排序

  • 创建一个触发器,根据需要使用大(或小)值填充该字段:

    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')