Oracle字母数字排序

Oracle字母数字排序,oracle,plsql,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_

我有这样的数据

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; 
Order by按以下顺序为我提供数据

213OUTD
1111111111231
CXL10570
OUTDR1004
OUTDR904
213OUTD
1111111111231
CXL10570
OUTDR904
OUTDR1004
但我希望我的数据按以下顺序排列

213OUTD
1111111111231
CXL10570
OUTDR1004
OUTDR904
213OUTD
1111111111231
CXL10570
OUTDR904
OUTDR1004

谢谢。

听起来你想做的是一种复合排序——你想按字母顺序对字母字符进行排序,但你想将数字字符分组在一起并作为数字处理

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填充中包含alpha部分


编辑2:更新为将“null first”添加到二级排序中。

听起来您想要做的是一种复合排序-您想要按字母顺序对字母字符进行排序,但您想要将数字字符分组在一起并作为数字处理

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填充中包含alpha部分


编辑2:更新为将“nulls first”添加到二级排序中。

您能解释一下您需要的逻辑吗?因为OUTDR904比OUTDR1004小。您有一些值以数字开头,一些值以数字结尾,其他值都是数字。我的感觉是,你应该修正你的数据模型,停止混合数字和文本数据。不能这样做,他们的业务就是这样:)你能解释一下你需求背后的逻辑吗?因为OUTDR904比OUTDR1004小。你有一些以数字开头的值,一些以数字结尾,其他都是数字。我的感觉是,你应该修正你的数据模型,停止混合数字和文本数据。不能这样做,他们的业务就是这样:)如果我有这样的数据
OUTDR1004,CXL10570,outdr904213outd,206207ab,211144
,我想把这些数据排序为
144206207ab,21121213outd,CXL10570,OUTDR904,OUTDR1004
。目前207AB出现在211之后,但我希望它立即出现在206之后。如果我有211B的数据,我希望它出现在211之后。目前的排序是211B,211。我要的是211211B。再次感谢您的支持,在二级排序中添加了“nulls first”。如果我有这样的数据
OUTDR1004、CXL10570、OutDR904213OUTD、206207AB、211144
,我希望将其排序为
144206207AB、21121213OUTD、CXL10570、OUTDR904、OUTDR1004
。目前207AB出现在211之后,但我希望它立即出现在206之后。如果我有211B的数据,我希望它出现在211之后。目前的排序是211B,211。我要的是211211B。再次感谢您,在第二次排序中添加了“nulls first”。