如何使用COLLATE NOCASE按不区分大小写的字母顺序排序

时间:2013-10-15 07:17:36

标签: sql oracle sorting

我正在尝试使用COLLATE NOCASE按字母顺序排序不区分大小写 但得到错误

  

ORA - 00933 SQL命令未正确结束。

下面是我正在解雇的查询:

SELECT LPN.LPN_ID, 
       LPN.TC_ORDER_ID, 
       ORDERS.D_NAME, 
       ORDERS.PURCHASE_ORDER_NUMBER AS ORDER_PURCHASE_ORDER_NUMBER, 
       ORDERS.D_NAME AS D_NAME_2, LPN.LPN_NBR_X_OF_Y 
  FROM ORDERS ORDERS, 
       LPN LPN 
 WHERE ORDERS.ORDER_ID=LPN.ORDER_ID 
 ORDER BY ORDERS.D_NAME COLLATE NOCASE DESC

我在这里试试这个,但仍然收到错误 How to use SQL Order By statement to sort results case insensitive? 有什么建议吗?

3 个答案:

答案 0 :(得分:6)

Oracle不支持COLLATE NOCASE子句的order by选项。为了能够执行不区分大小写的排序,您有两种选择:

  1. 设置NLS_COMP='ANSI''NLS_SORT=BINARY_CI'CI后缀表示不区分大小写,会话或系统范围,使用alter sessionalter system语句:< / p>

    alter session set nls_comp='ANSI';
    alter session set nls_sort='BINARY_CI';
    with t1(col) as(
     select 'A' from dual union all
     select 'a' from dual union all
     select 'b' from dual union all
     select 'B' from dual
    )
    select *
      from t1
     order by col
    

    结果:

    COL
    ---
    A
    a
    b
    B
    
  2. 使用upper()lower()函数更改字符文字的大小写。

      with t1(col) as(
        select 'A' from dual union all
        select 'a' from dual union all
        select 'b' from dual union all
        select 'B' from dual
      )
      select *
        from t1
       order by upper(col)
    

    结果:

    COL
    ---
     A
     a
     b
     B
    

  3. 修改

      

    但我需要UpperCase优先于任何LowerCase,例如。 Alan,alan,Brian,brian,Cris

    这不是不区分大小写的排序,而是在某种意义上相反。作为选项之一,您可以执行以下操作以产生所需的结果:

    with t1(col) as(
       select 'alan' from dual union all
       select 'Alan' from dual union all
       select 'brian' from dual union all
       select 'Brian' from dual union all
       select 'Cris' from dual
     )
     select col
       from ( select col
                   , case
                       when row_number() over(partition by lower(col) 
                                                  order by col) = 1
                       then 1
                       else 0
                     end as rn_grp
               from t1
             )
      order by sum(rn_grp) over(order by lower(col))
    

    结果:

    COL
    -----
    Alan
    alan
    Brian
    brian
    Cris
    

答案 1 :(得分:3)

COLLATE NOCASE不适用于Oracle,请尝试以下操作:

SELECT LPN.LPN_ID,
     LPN.TC_ORDER_ID,
     ORDERS.D_NAME,
     ORDERS.PURCHASE_ORDER_NUMBER AS ORDER_PURCHASE_ORDER_NUMBER,
     ORDERS.D_NAME AS D_NAME_2,
     LPN.LPN_NBR_X_OF_Y
FROM orders orders,
     lpn lpn
where orders.order_id=lpn.order_id
ORDER BY lower(orders.d_name) DESC;

答案 2 :(得分:3)

因为10g有一个函数NLSSORT,它几​​乎完成了Nicholas Krasnov described,但不需要改变系统或会话。

所以你可以尝试这样的事情:

SELECT LPN.LPN_ID, LPN.TC_ORDER_ID, ORDERS.D_NAME, ORDERS.PURCHASE_ORDER_NUMBER
AS ORDER_PURCHASE_ORDER_NUMBER, ORDERS.D_NAME AS D_NAME_2, LPN.LPN_NBR_X_OF_Y 
FROM ORDERS ORDERS, LPN LPN 
WHERE ORDERS.ORDER_ID=LPN.ORDER_ID 
ORDER BY nlssort(ORDERS.D_NAME, 'NLS_SORT = binary_ci') desc

请注意,您不能在UNION中直接使用它,否则您将收到以下错误:

  

ORA-01785:ORDER BY项必须是SELECT列表的编号   表达

相反,你需要包装它:

SELECT * FROM (SELECT a, b FROM x, y UNION SELECT c, d FROM m, n)
ORDER BY nlssort(a, 'nls_sort=binary_ci') DESC