更改NULL在排序中的位置

时间:2012-06-08 09:53:18

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

我正在整理一张桌子。可以找到小提琴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值视为高于任何其他值。是否可以这样做?

3 个答案:

答案 0 :(得分:4)

使用'end of time'标记来替换空值:

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

答案 1 :(得分:4)

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

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

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

ORDER BY COALESCE(field,'99991231') DESC

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

答案 2 :(得分:1)

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

对于较小的数据集,这可能不是问题,但如果它们变大则可能不是问题。应该通过定期对查询执行测试来监视这一点。如果您的数据永远不会发生变化(非常罕见),数据库优化只是一种“一劳永逸”的操作。

有时引入人工主排序列会更好,例如:

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列上的快速索引查找。高级执行引擎实际上可以同时运行这两个查询,并在它们完成后将它们组合起来。