【问题标题】:Oracle SQL order by Varchar2 with '_'带有'_'的 Varchar2 的 Oracle SQL 订单
【发布时间】:2019-12-27 15:19:35
【问题描述】:

我有一个带有 varchar2 列的表。按该列排序并没有给我预期的结果:

with test (col) as
  (select '_83_' from dual union all
   select '_81_' from dual union all
   select '4___' from dual union all
   select '____' from dual
  )
select * from test
order by col desc;

返回:

Col 
1. '_83_'
2. '_81_'
3. '4___'
4. '____'

我确实期待:

Col 
1. '4___'
2. '_83_'
3. '_81_'
4. '____'

您能否解释一下并帮助我将'4___' 放在我的订单声明的开头?

使用 Littlefoots 语句编辑可预生产性...

编辑我使用的是 Oracle 12c

编辑 NLS_Sort 设置为德语。这就是问题所在。

【问题讨论】:

  • 你能把样本数据和预期的输出也放上吗,这很难用更少的信息提出任何建议。
  • 可以设置NLS_SORT为二进制或者使用order by nlssort(column1, 'NLS_SORT = BINARY') desc,但是不知道为什么Oracle默认忽略下划线。
  • NLS_SORT 设置的当前值是多少?
  • @PonderStibbons 因为如果排序设置是语言设置,oracle 会忽略下划线。基于 ASCII 表的排序或 BINARY 为语言 NLS_SORT 定义下划线的不同排序规则
  • @PonderStibbons 这样的,你的意思是? docs.oracle.com/cd/B19306_01/server.102/b14225/ch5lingsort.htm

标签: sql oracle sql-order-by


【解决方案1】:

我不明白这个问题。是的,评论会更合适,但我不能发布这个:

SQL> with test (col) as
  2    (select '_83_' from dual union all
  3     select '_81_' from dual union all
  4     select '4___' from dual union all
  5     select '____' from dual
  6    )
  7  select * from test
  8  order by col;

COL
----
____
4___
_81_
_83_

SQL>

如您所见,我的结果与您的不同,即我无法重现您所说的内容。请您再解释一下好吗?

【讨论】:

  • 我的结果也不一样 4___ 81 83 ____
  • @MansiRaval 你的意思是你的结果与 littlefoot 不同?
  • 你运行:order by col;我运行:按 col desc 排序;
  • 但是你和我在 ____ 和 _ 之间有 4___ 81 _ 这是我没有得到的部分......我期待 Mansi Raval 得到什么......
  • @CaiusJard 是的 ______ 在我的情况下是最后一个。
【解决方案2】:

使用 Oracle 11g R2:

Select Column1 From (
    SELECT CAST( '_83_' AS varchar2(4) ) AS Column1 FROM dual
    union all
    SELECT CAST( '_81_' AS varchar2(4) ) AS Column1 FROM dual
    union all
    SELECT CAST( '4___' AS varchar2(4) ) AS Column1 FROM dual
    union all
    SELECT CAST( '____' AS varchar2(4) ) AS Column1 FROM dual
) A order by Column1  desc

输出:

____
_83_
_81_
4___

【讨论】:

    【解决方案3】:

    在我的本地数据库中,NLS_SORT 设置为 BINARY,因此不可重现。

    WITH TEMO AS 
    (
    SELECT '_83_' AS X FROM DUAL UNION ALL
    SELECT '_81_' AS X FROM DUAL UNION ALL
    SELECT '4___' AS X FROM DUAL UNION ALL
    SELECT '____' AS X FROM DUAL
    )
    SELECT * FROM TEMO ORDER BY X DESC;
    
    X   
    ----
    ____
    _83_
    _81_
    4___
    

    但是,在将NLS_SORTBINARY 更改为GERMAN 后,问题又重现了。

    ALTER SESSION SET NLS_SORT=GERMAN;
    
    WITH TEMO AS 
    (
    SELECT '_83_' AS X FROM DUAL UNION ALL
    SELECT '_81_' AS X FROM DUAL UNION ALL
    SELECT '4___' AS X FROM DUAL UNION ALL
    SELECT '____' AS X FROM DUAL
    )
    SELECT * FROM TEMO ORDER BY X DESC;
    
    X   
    ----
    _83_
    _81_
    4___
    ____
    

    您可以使用下表检查 NLS 值:

    NLS_SESSION_PARAMETERS
    NLS_DATABASE_PARAMETERS
    

    所以结论是NLS_SORT 参数必须相应设置,因为不是每个人都想使用技术进行排序。

    NLS_SORT的默认值派生自NLS_LANGUAGE

    有关 NLS_SORT 的更多信息,请参阅 oracle documents

    解决方法是根据需要更改NLS_SORT

    干杯!!

    【讨论】:

    • 你找到了 :-) ... 但是,在将 NLS_SORT 从 BINARY 更改为 GERMAN 后,问题重现了......
    • 您可以将 nls_sort 值更改为 null,并且可以将值分配为 AMERICAN 到 nls_language。 v$parameter Name =nls_sort and value =null name =nls_language and value=AMERICAN
    【解决方案4】:

    我个人推荐 Tejash 的答案,但你也可以用类似这样的东西来捏造它:

    SELECT * FROM table ORDER BY TRANSLATE(col, '_', 'z') desc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-12
      • 2017-05-26
      • 2018-02-20
      • 2016-07-08
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多