【问题标题】:SQL Server equivalent to Oracle's NULLS FIRST?SQL Server 相当于 Oracle 的 NULLS FIRST?
【发布时间】:2010-11-30 05:02:18
【问题描述】:

所以 Oracle 有 NULLS FIRST,我可以使用它让 null 值在顶部排序,然后按降序排列我的列值:

ORDER BY date_sent NULLS FIRST

SQL Server 中有什么可比性?假设日期值为 NULL 或过去,则有以下替代方法:

ORDER BY ISNULL(date_sent, GETDATE()) DESC
ORDER BY (CASE WHEN t.setinactive IS NULL THEN 1 ELSE 2 END), t.setinactive DESC
ORDER BY -CAST(date_sent as int) ASC

还有其他人吗?

【问题讨论】:

标签: sql sql-server sql-server-2005 tsql


【解决方案1】:

据我所知,你无法控制这一点。看起来您使用ISNULL 的方法是正确的。

对于字符串,我将ISNULL(field, '') 用于相同目的。

【讨论】:

  • Kev:这完全取决于手头问题的性质。问题不是“这是在所有情况下都使用的 ORDER BY 子句吗?”因此 G Mastros 的观点得到了很好的注意,但并不严格地放在问题本身的关键路径上。 rexem 正在寻找一种更全球化的方式来控制 NULL 排序。
【解决方案2】:

Use Case/When 语句,例如:

ORDER BY (case WHEN ColINT IS NULL THEN {maxIntValue} ELSE ColINT END) DESC

ORDER BY (case WHEN ColVChar IS NULL THEN {maxVCharValue} ELSE ColVChar END) DESC

ORDER BY (case WHEN ColDateT IS NULL THEN {maxDateTValue} ELSE ColDateT END) DESC

...等等。

甚至更好,因为您不关心您的列类型和最大值是什么。

ORDER BY (case WHEN ColAnyType IS NULL THEN 1 ELSE 0 END) DESC, ColAnyType DESC

【讨论】:

    【解决方案3】:

    你可以做一些技巧:

    ORDER BY (CASE WHEN [Order] IS NULL THEN 0 ELSE 1 END), [Order] 
    

    【讨论】:

    • 通过这个技巧,您可以实现任何您想要的排序。您甚至可以模仿多种语言中更通用的 IComparer 界面。
    • 请记住,如果您以前使用索引,这会严重降低性能,因为现在必须手动对结果进行排序。
    【解决方案4】:

    如果您的表中有行的日期小于现在,而其他行的日期大于现在,则您的 NULLS 将出现在列表的中间。相反,您可能应该使用一个永远不会在列表中间排序的值。

    Order by IsNull(Date_Sent, '17530101') desc

    注意:那个日期实际上是 1753 年 1 月 1 日。

    【讨论】:

    • Order by IsNull(Date_Sent, '17530101') desc 将确保我的具有空 date_sent 值的列出现在底部,而不是顶部。你是对的,但我不会去未来设置 date_sent 值 =)
    • 好点,但原则仍然成立。您应该使用不会自然出现在数据中的值。例如:按 IsNull(Date_Sent, '99990101') desc 排序
    • 完全同意使用标记值。
    【解决方案5】:
    ORDER BY
      COALESCE(POSTING_DATE,'1900-01-01 00:00:00.000')
     ,OTHER_FIELDS
    

    【讨论】:

    • 不起作用 - 首先是空值,但其余的 date_sent 列未按 DESC 顺序排序。
    【解决方案6】:

    当您想要调整空值在排序顺序中的显示方式时,这是一种替代方法。否定该列并反转您的排序顺序。不幸的是,您需要 CAST dateTime 列。

    ORDER BY -CAST(date_sent as int) ASC
    

    【讨论】:

    • 确认:Nulls在顶部,非null值按DESC顺序。
    【解决方案7】:

    一个简单的例子:

    SELECT (CASE WHEN Value1 IS NULL THEN 1 ELSE 0 END) AS ValueIsNull, Value1, Value2, Value3
    FROM TableName
    ORDER BY ValueIsNull DESC, Value1 
    

    【讨论】:

      【解决方案8】:

      快速回答是:在必要的情况下更改空值排序的最佳解决方案是接受的解决方案。但是你只需要使用它,或者在必要的情况下使用它的变体:

      • DESC + NULLS FIRST:

        ORDER BY (CASE WHEN [Order] IS NULL THEN 0 ELSE 1 END), [Order] DESC

      • ASC + NULLS LAST:

        ORDER BY (CASE WHEN [Order] IS NULL THEN 1 ELSE 0 END), [Order] ASC

      • ASC + NULLS FIRST:默认情况下可以正常工作

      • DESC + NULLS LAST:默认情况下可以正常工作

      让我们看看为什么:

      如果您查看ORDER BY Clause (Transact-SQL) MSDN docs,并向下滚动到ASC | DESC,您可以阅读以下内容:

      升序 | DESC

      指定指定列中的值应按升序或降序排序。 ASC 从最低值到最高值排序。 DESC 从最高值到最低值排序。 ASC 是默认的排序顺序。 Null 值被视为可能的最低值。

      因此,默认情况下,如果您指定ASC 订单,它的工作方式类似于NULLS FIRST。而且,如果您指定DESC,它的工作方式类似于NULLS LAST

      所以你只需要在DESC 顺序中更改NULLS FIRST 的行为,在ASC 顺序中更改NULLS LAST 的行为。

      恕我直言,在必要的情况下更改空值排序的最佳解决方案是已接受的解决方案,但我在回答的开头已经包含了它以适应不同的情况。

      【讨论】:

        猜你喜欢
        • 2010-12-30
        • 1970-01-01
        • 2016-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        • 1970-01-01
        • 2023-02-23
        相关资源
        最近更新 更多