Oracle 字母数字列排序
Oracle Alpha-Numeric column sorting
我正在按照下面的 asc 顺序对 Oracle 数据库 table 的修订列进行排序。
首先要排序的数字修订(1,2,3,...)。
此后字母数字排序如下:A、B、B1、C、C1、C2、…、Y、Y2、Y3、Z、AA、AB、..、DA、…ZZ 等。
Row_Number() 在SELECT 语句中对每个文档#(ABC, XYZ) 补1,2,3… 修改整理后。
所需table见上传图片。
我尝试使用 SUBSTR 、 Order by 等,但未能按照上述要求进行排序。
有人可以帮我吗?谢谢!
据我了解您的问题,您希望输入仅包含两个字符且不含数字的最新修订版。
您可以使用条件排序:
select
t.*,
row_number() over(
partition by doc#
order by
case when regexp_like(revision, '^\w\d?$') then 0 else 1 end,
revision
) rn
from t
order by doc#, rn
正则表达式描述了一个以字母数字字符开头的字符串,可以选择后跟一个数字:这些修订应该放在第一位。
Demo on DB Fiddle:
with t as (
select 'ABC' doc#, '1' revision from dual
union all select 'ABC', '2' from dual
union all select 'ABC', '3' from dual
union all select 'ABC', 'A' from dual
union all select 'ABC', 'B' from dual
union all select 'ABC', 'B1' from dual
union all select 'ABC', 'C' from dual
union all select 'ABC', 'C1' from dual
union all select 'ABC', 'D' from dual
union all select 'ABC', 'AA' from dual
union all select 'ABC', 'AB' from dual
union all select 'ABC', 'BA' from dual
union all select 'ABC', 'DA' from dual
)
select
t.*,
row_number() over(
partition by doc#
order by
case when regexp_like(revision, '^\w\d?$') then 0 else 1 end,
revision
) rn
from t
order by doc#, rn
DOC# | REVISION | RN
:--- | :------- | -:
ABC | 1 | 1
ABC | 2 | 2
ABC | 3 | 3
ABC | A | 4
ABC | B | 5
ABC | B1 | 6
ABC | C | 7
ABC | C1 | 8
ABC | D | 9
ABC | AA | 10
ABC | AB | 11
ABC | BA | 12
ABC | DA | 13
有一个众所周知的旧方法:rpad(col, max-length, '0')
例如 rpad(col, max(length(col)) over(), '0'
我正在按照下面的 asc 顺序对 Oracle 数据库 table 的修订列进行排序。 首先要排序的数字修订(1,2,3,...)。 此后字母数字排序如下:A、B、B1、C、C1、C2、…、Y、Y2、Y3、Z、AA、AB、..、DA、…ZZ 等。 Row_Number() 在SELECT 语句中对每个文档#(ABC, XYZ) 补1,2,3… 修改整理后。
所需table见上传图片。
我尝试使用 SUBSTR 、 Order by 等,但未能按照上述要求进行排序。 有人可以帮我吗?谢谢!
据我了解您的问题,您希望输入仅包含两个字符且不含数字的最新修订版。
您可以使用条件排序:
select
t.*,
row_number() over(
partition by doc#
order by
case when regexp_like(revision, '^\w\d?$') then 0 else 1 end,
revision
) rn
from t
order by doc#, rn
正则表达式描述了一个以字母数字字符开头的字符串,可以选择后跟一个数字:这些修订应该放在第一位。 Demo on DB Fiddle:
with t as (
select 'ABC' doc#, '1' revision from dual
union all select 'ABC', '2' from dual
union all select 'ABC', '3' from dual
union all select 'ABC', 'A' from dual
union all select 'ABC', 'B' from dual
union all select 'ABC', 'B1' from dual
union all select 'ABC', 'C' from dual
union all select 'ABC', 'C1' from dual
union all select 'ABC', 'D' from dual
union all select 'ABC', 'AA' from dual
union all select 'ABC', 'AB' from dual
union all select 'ABC', 'BA' from dual
union all select 'ABC', 'DA' from dual
)
select
t.*,
row_number() over(
partition by doc#
order by
case when regexp_like(revision, '^\w\d?$') then 0 else 1 end,
revision
) rn
from t
order by doc#, rn
DOC# | REVISION | RN :--- | :------- | -: ABC | 1 | 1 ABC | 2 | 2 ABC | 3 | 3 ABC | A | 4 ABC | B | 5 ABC | B1 | 6 ABC | C | 7 ABC | C1 | 8 ABC | D | 9 ABC | AA | 10 ABC | AB | 11 ABC | BA | 12 ABC | DA | 13
有一个众所周知的旧方法:rpad(col, max-length, '0')
例如 rpad(col, max(length(col)) over(), '0'