【问题标题】:Random sorting with ORDER BY with CASE clause使用带有 CASE 子句的 ORDER BY 进行随机排序
【发布时间】:2017-11-06 11:17:55
【问题描述】:

我正在用 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 

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

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

【问题讨论】:

  • @YogeshSharma 完成
  • @YogeshSharma 我的错,对不起

标签: sql oracle case


【解决方案1】:

在 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 表达式只有在等式计算为TRUE 时才会计算为1,并且当等式的至少一侧是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 之前排序,因此未来的开发人员知道这是您的预期排序(而不仅仅是一个查询的无意副作用)。

【讨论】:

  • 感谢您的澄清。你知道这是否也适用于 denodo 的 VQL?
  • @MichaelBobryashov 不知道,因为我从未使用过 Denodo - 如果您需要对此的答案,那么您可以查看是否可以在他们的文档中找到它,或者使用适当的标签将其作为新问题提出(以便 Denodo 专家解答)。
【解决方案2】:

将列two 添加为三阶条件

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

二阶条件只将空条目放在首位,而不是更多。

【讨论】:

  • 谢谢,它有效!那么,“else 0”部分意味着忽略任何其他值?
  • case 产生 2 个值:0 或 1。您按此排序。这意味着 1 值首先出现在列表中,然后是所有 0 值。
  • @MichaelBobryashov CASE 表达式,在这里,将始终计算为 0 所以这个 ORDER BY 子句等效于 ORDER BY One DESC, Two DESCdefault is for DESC ordering to be NULLS FIRSTCASE 表达式是没用)。
  • 解释为什么会这样是完全错误的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 2017-04-10
相关资源
最近更新 更多