使用带有CASE子句的ORDER BY进行随机排序

时间:2017-11-06 11:17:56

标签: sql oracle case

我正在使用CASE测试ORDER BY子句,并遇到了这个问题。

我的测试选择声明:

SELECT to_date as "One", field1 as "Two"
   FROM(
        SELECT to_date('yyyy-mm-dd', '2017-10-10'), '333' union all
        SELECT to_date('yyyy-mm-dd', '2017-09-09'), '111' union all
        SELECT to_date('yyyy-mm-dd', '2017-09-09'), '222' union all
        SELECT to_date('yyyy-mm-dd', '2017-09-09'), '' union all
        SELECT to_date('yyyy-mm-dd', '2017-09-09'), ''
        )
   ORDER BY One DESC,
          CASE when Two = '' then 1 
               else 0 end DESC 

结果可能会有所不同,按第二列排序是随机的: enter image description here enter image description here

如何修改CASE子句以避免它?

2 个答案:

答案 0 :(得分:2)

在Oracle中,empty string '' is the identical to NULL所以您的查询是:

ORDER BY
  One DESC,
  CASE when Two = NULL then 1 else 0 end DESC

比较值时,可能的状态为:

Equality                 Result
------------------------ ------
value = value            TRUE
value = other_value      FALSE
value = NULL             NULL
NULL  = NULL             NULL

当等式求值为CASE时,1表达式将仅评估为TRUE,并且当等式的至少一侧为NULL时,这将永远不会是结果

您想要的是使用IS NULL而不是= ''

ORDER BY
  One DESC,
  CASE WHEN Two IS NULL THEN 1 ELSE 0 END DESC,
  Two DESC;

您可以简化为:

ORDER BY
  One DESC,
  Two DESC NULLS FIRST;

DESC订购的默认设置为NULLS FIRST,因此您可以进一步简化为:

ORDER BY
  One DESC,
  Two DESC;

但是,我不会这么做,因为您最好明确说明您希望在非NULL之前订购NULL值,以便未来的开发人员知道这是您的预期订购(而不仅仅是你的查询的无意的副作用。)

答案 1 :(得分:1)

将列two添加为第三顺序条件

ORDER BY One DESC,
         CASE when Two = '' then 1 else 0 end DESC,
         Two DESC

第二顺序条件只会先输入空条目而不是更多。