Oracle Order by - 基于函数 (dense_rank)

Posted

技术标签:

【中文标题】Oracle Order by - 基于函数 (dense_rank)【英文标题】:Oracle Order by - Function Based (dense_rank) 【发布时间】:2016-09-05 21:15:57 【问题描述】:

我有一个表,其中包含以下 4 列和一些示例数据

Aisle | Rack | Level | Position
  1        1       1         1
  1        2       1         2
  2        1       1         1
  2        2       1         1
  2        3       1         1
  3        1       1         1
  3        2       1         1

我希望编写一个可以使用以下方法对记录进行排序的查询

过道第一(上升)

然后通过货架(上升到一个过道,下降到下一个过道, 很快。 . .这是我似乎无法弄清楚是否可以的部分 在Oracle中实现)

然后按级别(升序)

然后按位置(升序)

所以得到的有序行如下

 Aisle | Rack | Level | Position
  1        1       1         1
  1        2       1         2
  2        3       1         1
  2        2       1         1
  2        1       1         1
  3        1       1         1
  3        2       1         1

我们按照条款制定了以下顺序

order by aisle,
      (case when mod(dense_rank() over (order by aisle), 2) = 1 then rack else - rack
       end),
      level,
      position

但是,我在执行查询时收到错误“ORA-00932:不一致的数据类型:预期的 CHAR 得到 NUMBER”。这些列都是 VARCHAR2 类型。

我能做些什么来让它发挥作用?

【问题讨论】:

【参考方案1】:

如果列是varchar2(),那么一元减号就不能很好地工作。

这个怎么样?

order by aisle,
      (case when mod(dense_rank() over (order by aisle), 2) = 1 then rack end) asc,
      (case when mod(dense_rank() over (order by aisle), 2) = 0 then rack end) desc,
      level,
      position

【讨论】:

非常感谢。【参考方案2】:

您可以按rack 升序/降序排序,但如果您将rack 保留为varchar2,那么9 将按升序排列在10 之前(因为您是按字母顺序排序,而不是按数字排序)字符 1 在 9 之前)。

除非这是预期的行为(可能是,但它是不寻常的),最好将所有出现的rack 包装在to_number() 中,即按to_number(rack) 排序 - 无论是在您的原始尝试(现在应该可以使用此修改)或在 Gordon 的解决方案中 - 如果您不使用 to_number(),可能会遇到“字母顺序”问题。

【讨论】:

以上是关于Oracle Order by - 基于函数 (dense_rank)的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Oracle 的窗口函数中使用 ORDER BY 子句

oracle常用分析函数 over(partition by xxx order by xxx)

oracle使用order by排序null值如何处理?

oracle系统包——dbms_random用法及order by 小结(转)

oracle的row_number() OVER (ORDER BY COL2 asc)和row_number() OVER (PARTITION BY COL1 ORDER BY COL2)的用法

oracle不可以用order by么