[英]Sort alphanumeric ID number
我有一個數據庫,每筆交易都有一個字母數字 ID。 當我編寫查詢並使用 Order by 時,它會給我一個錯誤的順序。
例如:
TRN_ID TRNDTE
000002DAAW 2020-09-12 03:45:24
000002DAAX 2020-09-12 03:45:32
000002DAAY 2020-09-12 03:45:34
000002DAAZ 2020-09-12 03:45:38
000002DAA0 2020-09-12 03:35:16
000002DAA1 2020-09-12 03:35:25
000002DAA2 2020-09-12 03:35:26
000002DAA3 2020-09-12 03:35:30
000002DAA4 2020-09-12 03:35:39
000002DAA5 2020-09-12 03:35:40
000002DAA6 2020-09-12 03:35:44
000002DAA7 2020-09-12 03:36:00
000002DAA8 2020-09-12 03:36:01
000002DAA9 2020-09-12 03:36:05
000002DABA 2020-09-12 03:48:12 <-
000002DABB 2020-09-12 03:48:15
000002DABC 2020-09-12 03:48:32
000002DABD 2020-09-12 03:48:33
000002DABE 2020-09-12 03:48:36
000002DABF 2020-09-12 03:48:46
000002DABG 2020-09-12 03:48:47
000002DABH 2020-09-12 03:48:50
000002DABI 2020-09-12 03:49:06
000002DABJ 2020-09-12 03:49:06
000002DABK 2020-09-12 03:49:09
000002DABL 2020-09-12 03:49:19
000002DABM 2020-09-12 03:49:20
000002DABN 2020-09-12 03:49:24
000002DABO 2020-09-12 03:49:33
000002DABP 2020-09-12 03:49:34
000002DABQ 2020-09-12 03:49:37
000002DABR 2020-09-12 03:49:48
000002DABS 2020-09-12 03:49:48
000002DABT 2020-09-12 03:49:51
000002DABU 2020-09-12 03:50:01
000002DABV 2020-09-12 03:50:01
000002DABW 2020-09-12 03:50:05
000002DABX 2020-09-12 03:50:15
000002DABY 2020-09-12 03:50:15
000002DABZ 2020-09-12 03:50:18
000002DAB0 2020-09-12 03:46:23 <-
000002DAB1 2020-09-12 03:46:24
000002DAB2 2020-09-12 03:46:28
000002DAB3 2020-09-12 03:47:18
000002DAB4 2020-09-12 03:47:18
如您所見,查詢是先從 A 到 Z,然后從 0 到 9,但它應該先從 0 到 9,然后再從 A 到 Z
有一種方法可以設置一個字符串來正確排序嗎?
Trincot 的觀察(您的問題下的第二條評論)很可能是正確的:您看到在數字之前使用字母升序排列(而不是相反),因為您的排序規則需要它。
根據您的個人資料,我假設您在巴西,並且您的NLS_LANGUAGE
參數為'BRAZILIAN PORTUGUESE'
,默認NLS_SORT
參數(源自NLS_LANGUAGE
)為'WEST_EUROPEAN'
。 這不是甲骨文的選擇。 巴西葡萄牙語排序規則(或更准確地說,西歐排序規則)在字母之后有數字,而不是在它們之前。 請參閱此答案末尾的演示。
所以,這就解釋了問題。 你怎么能解決它?
如果您有很多類似的查詢,並且您必須在所有查詢中的字母之前顯示數字(或者如果您在查詢中的許多地方都有ORDER BY
- 例如在分析函數中或match_recognize
等),那么它更改 session 的NLS_SORT
參數是有意義的,使用
alter session set nls_sort='BINARY';
如果您只需要在單個查詢中執行此操作,在ORDER BY
子句中,您可以使用NLSSORT
function 在本地更改排序順序(僅針對該ORDER BY
子句,而不影響其他任何內容)。 像這樣:
.... order by nlssort(TRN_ID, 'NLS_SORT=BINARY')
這是一個簡短的演示。
首先,在我的系統上, NLS_LANGUAGE
是'AMERICAN'
,默認NLS_SORT
(對於這種語言)是'BINARY'
。 這就是為什么字母在數字之后的原因:
select col
from (select 'A' as col from dual union all select '3' from dual)
order by col;
COL
---
3
A
現在讓我將我的NLS_LANGUAGE
更改為'BRAZILIAN PORTUGUESE'
。 然后讓我們看看這如何影響NLS_SORT
(自動),以及它對查詢的影響:
alter session set nls_language='BRAZILIAN PORTUGUESE';
select parameter, value
from v$nls_parameters
where parameter in ('NLS_LANGUAGE', 'NLS_SORT');
PARAMETER VALUE
------------ ----------------------
NLS_LANGUAGE BRAZILIAN PORTUGUESE
NLS_SORT WEST_EUROPEAN
select col
from (select 'A' as col from dual union all select '3' from dual)
order by col;
COL
---
A
3
現在,在不更改語言的情況下,讓我將整理順序( NLS_SORT
參數)更改為'BINARY'
- 並查看查詢如何產生所需的結果。 我們沒有更改語言,但我們更改了整個 session 的整理順序。 這將適用於當前 session 中的所有其他查詢。
alter session set nls_sort='BINARY';
select parameter, value
from v$nls_parameters
where parameter in ('NLS_LANGUAGE', 'NLS_SORT');
PARAMETER VALUE
------------ ----------------------
NLS_LANGUAGE BRAZILIAN PORTUGUESE
NLS_SORT BINARY
select col
from (select 'A' as col from dual union all select '3' from dual)
order by col;
COL
---
3
A
最后,讓我將NLS_SORT
改回'WEST_EUROPEAN'
並在查詢的ORDER BY
子句中使用NLSSORT
function 以獲得相同的結果(您需要的結果),而無需觸及 session 參數。
alter session set nls_sort='WEST_EUROPEAN';
select col
from (select 'A' as col from dual union all select '3' from dual)
order by col; -- This will produce the wrong order! See below for fix.
COL
---
A
3
select col
from (select 'A' as col from dual union all select '3' from dual)
order by nlssort(col, 'nls_sort=BINARY');
COL
---
3
A
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.