我有一个带有 varchar2 的“标题”字段的表,我想选择所有行并首先按数字对它们进行排序,然后按通常发生的字母排序。
例如,我目前ORDER BY title
在最后使用一个简单的方法得到这个:
- 美国广播公司
- 定义
- 321
但我想要这个:
- 321
- 美国广播公司
- 定义
奇怪的是,SQL Developer 显示了“正确”的顺序,数字在前。但在我的应用程序(使用 OCI8 的 PHP)上,它最后显示数字。
我有一个带有 varchar2 的“标题”字段的表,我想选择所有行并首先按数字对它们进行排序,然后按通常发生的字母排序。
例如,我目前ORDER BY title
在最后使用一个简单的方法得到这个:
但我想要这个:
奇怪的是,SQL Developer 显示了“正确”的顺序,数字在前。但在我的应用程序(使用 OCI8 的 PHP)上,它最后显示数字。
不是 Oracle 专家,但您应该能够在不更改会话的情况下使用
SELECT * FROM my_data SORT by NLSSORT(title,’NLS_SORT=BINARY_AI’)
您可以在哪里更改NLS_SORT=
以满足您的需要(这里是值列表)
请记住,文档说这将强制进行表扫描,因此首先过滤它们可能是有益的(但如果您选择所有表扫描,那么无论如何您都将使用)。
SQL Developer 表现出不同行为的原因可能是因为它改变了会话。
您看到的行为差异可能是由于不同的NLS_SORT
参数设置。考虑:
SQL> select * from nls_session_parameters where parameter='NLS_SORT';
PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_SORT BINARY
SQL> SELECT * FROM my_data order by title;
TITLE
-----
321
Abc
Def
SQL> alter session set nls_sort=french;
Session altered
SQL> SELECT * FROM my_data order by title;
TITLE
-----
Abc
Def
321
无论您的NLS_SORT
会话参数设置如何,您都可以构建一个应该给您预期结果的查询,例如:
SQL> SELECT *
2 FROM my_data
3 ORDER BY CASE
4 WHEN regexp_like(title, '[0-9]+\.?[0-9]*') THEN
5 1
6 ELSE
7 2
8 END, title;
TITLE
-----
321
Abc
Def