Oracle字母数字排序

时间:2018-06-25 13:38:11

标签: oracle plsql

我有这样的数据

select x FROM (
select 'OUTDR1004' x from dual union all
select 'CXL10570' x from dual union all
select 'OUTDR904' x from dual union all 
select '213OUTD' x from dual union all 
select '1111111111231' x from dual 
) order by case when regexp_like(x,'^[[:digit:]]') then LPAD(x,50, '0') else x end; 

按以下顺序提供给我数据

213OUTD
1111111111231
CXL10570
OUTDR1004
OUTDR904

但是我想要我的数据按以下顺序

213OUTD
1111111111231
CXL10570
OUTDR904
OUTDR1004

谢谢。

1 个答案:

答案 0 :(得分:3)

听起来您想做的是复合排序-您想按字母顺序对字母字符进行排序,但是您希望将数字字符分组在一起并视为数字。

select x
FROM (
select '144' x from dual union all
select '211' x from dual union all
select '211B' x from dual union all 
select '207AB' x from dual union all 
select '213OUTD' x from dual  union all 
select '1111111111231' x from dual union all
select 'OUTDR1004' x from dual union all
select 'CXL10570' x from dual union all
select 'OUTDR904' x from dual
) order by case
    -- starts with number, pad number part with zeros to sort numerically
    when regexp_like(x,'^[[:digit:]]') then lpad(regexp_substr(x, '^[[:digit:]]+'),50,'0')  
    -- if x starts with non-numeric, primary sort the alpha portion
    when regexp_like(x, '^[^[:digit:]]') then regexp_substr(x, '^[^[:digit:]]+') 
    else x end,
   -- if x starts with a non-numeric, secondary sort by the numeric portion (zero padded)
   case when regexp_like(x, '^[^[:digit:]]') then lpad(regexp_substr(x, '[[:digit:]]+$'),50,'0')
     -- if x starts with a numeric, secondary sort by the alpha portion
     when regexp_like(x, '^[[:digit:]]') then regexp_substr(x, '[^[:digit:]]+$')
     else x end nulls first; 

希望您只看到此处显示的案例,而没有302OUTDR378之类的案例,否则这种排序逻辑将很快变得难以管理。

编辑:已更新,以停止在填充0中包含字母部分。

编辑2:已更新,将“空值优先”添加到次级排序中。