5

我正在尝试使用不区分大小写的字母顺序排序,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

我在这里检查以尝试此操作,但仍然出现错误 如何使用 SQL Order By 语句对结果进行排序不区分大小写? 请问有什么建议吗?

4

3 回答 3

6

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

  1. 通过 using or语句设置NLS_COMP='ANSI'and 'NLS_SORT=BINARY_CI'CI后缀表示不区分大小写、会话或系统范围:alter sessionalter system

    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()orlower()函数更改字符文字的大小写。

      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
    

编辑

但我需要大写字母在任何小写字母之前,例如。艾伦,艾伦,布赖恩,布赖恩,克里斯

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

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
于 2013-10-15T07:27:36.193 回答
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;
于 2013-10-15T07:28:27.427 回答
3

从 10g 开始,有一个函数NLSSORT几乎完成了Nicholas Krasnov 所描述的工作,但不需要更改系统或会话。

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

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
于 2013-10-15T07:33:39.720 回答