按多列排序,忽略Null

时间:2018-06-11 20:06:15

标签: sql sql-server null sql-order-by sql-server-2016

我有一个视图,显示某个项目到达多个位置的时间。我想根据到达时间订购此视图:

ITEM | At Loc1 | At Loc2 | At Loc3 | At Loc4 | Desired Order
--------------------------------------------------------
aaa  | 00:00   | 02:01   | NULL    | 05:30   | 0
bbb  | NULL    | 02:30   | 06:21   | NULL    | 1
ccc  | 00:05   | 02:33   | NULL    | 07:10   | 2 
ddd  | 00:07   | NULL    | 06:25   | 09:00   | 3
eee  | NULL    | NULL    | 06:30   | 09:10   | 4
fff  | 00:30   | 02:55   | 06:32   | NULL    | 5

由于测量误差或不规则,有时不会记录到达时间。在这种情况下,时间是NULL

现在我要Select * from View ORDER BY AtLoc1 ASC, AtLoc2 ASC, AtLoc3 ASC, AtLoc4 ASC

但是列中的Null值不应该使项目转到前面或后面。根据下一栏,它应保持在正确的相对位置。

例如,项目bbb尚未记录在位置1,但是它在aaa之后和ccc之前到达位置2,因此它应该在aaa和ccc之间排序,而不是在列表的开头或结尾

在大多数情况下,商品不会在不同地点之间更改订单,但这并非不可能。

我认为我不能为所有特殊情况定义一个唯一且定义良好的排序顺序,当有太多的NULL聚集在一起时,那么顺序可能是未定义的。但我只想介绍空值相对稀疏的最常见情况。

如何以这种方式在SQL中订购视图?

2 个答案:

答案 0 :(得分:1)

需要更多测试,但请尝试以下方法:

<强> SQL DEMO

<unzip>

<强>输出

enter image description here

答案 1 :(得分:1)

不,你不能得到一个稳定的排序,因为你可以有这样的东西:

aaa     1      7
bbb  NULL      6
ccc     2      5

基本上,这三件事都是真的:

  • ccc&gt; AAA
  • bbb&gt; CCC
  • aaa&gt; BBB

这些不可能同时成立(至少不是数字 - 或时间 - 正如我们通常使用的那样)。

Juan Carlos提供了一个非常好的临时解决方案,但它并不适用于所有情况。