如何在不同情况下按列表排序(Oracle)

问题描述:

如何在具有不同情况下字符的varchar2列进行排序(UPPERlower)?如何在不同情况下按列表排序(Oracle)

例如,当我在名称列做一个订单,我得到如下结果:

ANNIE 
BOB 
Daniel 
annie 
bob 

我想是这样的:

ANNIE 
annie 
BOB 
bob 
Daniel 

使用lower(field),例如

select * from tbl order by lower(name) 

如果您需要处理非英语语言的特殊字符,那么关于NLSSORT的其他答案可能就是您需要的。如果你不这样做,我会尝试和KISS并使用lower(),因为它很容易记住和使用,并被他人阅读(可维护性)。

+1

有一点需要补充的是,这意味着除非'lower(name)'有一个函数索引,否则将使用此查询完成全表扫描。 – beny23 2012-03-20 15:00:45

+6

此查询将始终需要全表扫描,可以带或不带ORDER BY。通常,您所描述的问题对于WHERE子句更为重要。 – DCookie 2012-03-20 15:57:14

+3

@DCookie:你想赌吗? ;)例如试试'lower(name)'的函数索引,并附上table =完整索引扫描中的所有列,再加上没有排序:) - 只是说' – 2012-03-21 05:12:25

如果您使用的是相对较新版本的Oracle,则应该考虑设置NLS_SORT/NLS_COMP,而不是使用LOWER()函数。

如果您不想全局影响实例,则可以使用NLSSORT()函数为特定查询的范围设置NLS_SORT。

SQL> create table case_insensitive(a varchar2(10)); 

Table created. 

SQL> insert into case_insensitive values('D'); 

1 row created. 

SQL> 
SQL> 
SQL> c/'D/'c 
    1* insert into case_insensitive values('c') 
SQL>/

1 row created. 

SQL> c/'c/'B 
    1* insert into case_insensitive values('B') 
SQL>/

1 row created. 

SQL> c/'B/'a 
    1* insert into case_insensitive values('a') 
SQL>/

1 row created. 

SQL> commit; 

Commit complete. 

SQL> select * from case_insensitive; 

A 
---------- 
D 
c 
B 
a 

SQL> select * from case_insensitive order by a; 

A 
---------- 
B 
D 
a 
c 

SQL> select * from case_insensitive order by nlssort(a,'NLS_SORT=BINARY_CI'); 

A 
---------- 
a 
B 
c 
D 

的一个很好的例子可以发现here.

+0

设置NLS_SORT/NLS_COMP将改变所有查询的行为。如果那是我们想要的,那很好。如果不是这样,那就太好了。 – 2012-03-20 16:20:45

+0

不一定。我会回去编辑我的示例来演示。 – 2012-03-20 16:52:02

+0

NLSSORT和NLS_SORT都由Oracle定义,但是不同。这个答案的顶部引用了NLS_SORT,一个参数。但是,在我评论后添加的代码使用NLSSORT函数。因此,如果您最初的意思是NLSSORT,那么您的评论就不适用。 NLSSORT http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions113.htm#SQLRF00678,NLS_SORT http://docs.oracle.com/cd/E11882_01/server.112/e25513/initparams152。 htm#REFRN10127 – 2012-03-20 22:09:16

另一种选择是使用NLSSORT功能的执行linguistic sorting

SQL> with test as (select 'ANNIE' as col from dual 
    2  union all select 'BOB' from dual 
    3  union all select 'Daniel' from dual 
    4  union all select 'annie' from dual 
    5  union all select 'bob' from dual 
    6  union all select 'Ångström' from dual 
    7  union all select 'ångström' from dual) 
    8 select col 
    9 from test 
10 order by nlssort(col, 'NLS_SORT = WEST_EUROPEAN') 
11/

COL 
---------- 
Ångström 
ångström 
ANNIE 
annie 
BOB 
bob 
Daniel 

的优点是更多的灵活性。人们可以将带有口音的字符以及不同的情况一起分类。人们可以选择用specifying different values for NLS_SORT以特定语言对待某些字符。在一组等效字符中定义一个订单。所以'A'和'a'排序在一起,但在'a'中,大写字母首先出现。缺点我期望NLSSORT使用比LOWER更多的CPU,尽管我没有标记它。而NLSSORT只会使用的longer strings前缀:

返回的字符串,也被称为整理键,是RAW数据 类型。由给定排序规则的char 值产生的排序规则关键字的长度可能会超过2000字节,即NLSSORT返回的RAW值的最大长度的 。在这种情况下, NLSSORT计算char的最大前缀或子字符串的初始排序键,以便计算结果不超过2000 字节。对于单语排序规则,例如FRENCH,前缀 长度通常为1000个字符。对于多语言归类,对于 示例GENERIC_M,前缀通常为500个字符。确切的 长度可能会更低或更高,具体取决于char中包含的排序规则和 字符。

+0

有关使用索引进行语言排序的信息,请参阅http://docs.oracle.com/cd/E11882_01/server.112/e10729/ch5lingsort.htm#i1006421。 – 2012-03-20 16:21:42

+1

+1好例子。 – DCookie 2012-03-20 19:52:37

您可以通过cluse使用为了这个

select col_name from table_name 
order by col_name ; 

您可以使用INITCAP例如

SELECT fld FROM tbl ORDER BY INITCAP(fld) ASC; 
+1

没有理由提供比接受的答案好的答案。此外,initcap不会这样做(考虑'ANNA'和'annie')。 – 2015-12-02 17:27:55