【问题标题】:Changing NULL's position in sorting更改 NULL 在排序中的位置
【发布时间】:2012-06-12 09:10:31
【问题描述】:

我正在整理一张桌子。小提琴可以在here找到。

CREATE TABLE test
(
field date NULL
);

INSERT INTO test VALUES
('2000-01-05'),
('2004-01-05'),
(NULL),
('2008-01-05');

SELECT * FROM test ORDER BY field DESC;

我得到的结果:

2008-01-05
2004-01-05
2000-01-05
(null)

但是我需要这样的结果:

(null)
2008-01-05
2004-01-05
2000-01-05

因此 NULL 值被视为高于任何其他值。有可能吗?

【问题讨论】:

标签: sql sql-server sql-server-2008 sorting null


【解决方案1】:

最简单的方法是先添加一个额外的排序条件:

ORDER BY CASE WHEN field is null then 0 else 1 END,field DESC

或者,您可以尝试将其设置为其数据类型的最大值:

ORDER BY COALESCE(field,'99991231') DESC

COALESCE/ISNULL 工作正常,前提是您没有使用相同最大值的“真实”数据。如果这样做,并且需要区分它们,请使用第一种形式。

【讨论】:

  • 是的,数据属于正常范围,即当前天数,年份,(不超过 +-10 年):) 感谢您的回答 :)
  • 第一个选项是我的自然倾向。我目前无法访问数据库来测试我的假设,但我希望这样;如果结果集已经自然排序,则后者将计划使用更昂贵的重新排序例程,因为排序字段被ISNULL() 混淆,因此优化器无法know 关于关系在数据的自然顺序和期望的最终顺序之间。 (这有意义吗?)
【解决方案2】:

使用“时间结束”标记替换空值:

SELECT * FROM test 
ORDER BY ISNULL(field, '9999-01-01') DESC; 

【讨论】:

  • 嗯,在订购desc 并首先想要nulls 时,您想要的是时间的结束,而不是时间的开始
  • 啊哈!开始了!又一天,我学到了一些有价值的东西。谢谢你:)
【解决方案3】:

警惕调用每行函数的查询,它们很少能很好地扩展。

这对于较小的数据集可能不是问题,但如果它们变大了就会出现问题。这应该通过定期对查询执行测试来监控。如果您的数据从不更改(非常罕见),数据库优化只是一种设置后的操作。

有时最好引入人工的主排序列,例如:

select 1 as art_id, mydate, col1, col2 from mytable where mydate is null
union all
select 2 as art_id, mydate, col1, col2 from mytable where mydate is not null
order by art_id, mydate desc

那么只在你的程序中使用result_set["everything except art_id"]

通过这样做,您不会引入(可能)缓慢的每行函数,而是依赖于 mydate 列上的快速索引查找。高级执行引擎实际上可以同时运行这两个查询,并在它们都完成后将它们组合起来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 2018-01-16
    • 2021-06-10
    • 2011-06-24
    • 2019-04-07
    • 1970-01-01
    • 2013-06-14
    相关资源
    最近更新 更多