トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-12 数値にキャストしてソート

SQLパズル

ThreeTable
Val
--------
A-1
A-2
A-2-1
A-2-2
B-1
B-1-1
B-1-2
B-1-12
B-10-1
B-10-100

文字列フィールドに以下のパターンでランダムにデータが入る。
これをソートして出力する。

階層は、
1階層はAからZ固定
2階層と3階層目は数値(ゼロ埋めもなく桁数上限もなし)
2階層目までのデータもあり、3階層までのデータもある。

出力結果
Val
--------
A-1
A-2
A-2-1
A-2-2
B-1
B-1-1
B-1-2
B-1-12
B-10-1
B-10-100


データ作成スクリプト

create table ThreeTable(Val) as
select 'A-1'      from dual union
select 'A-2'      from dual union
select 'A-2-1'    from dual union
select 'A-2-2'    from dual union
select 'B-1'      from dual union
select 'B-1-1'    from dual union
select 'B-1-2'    from dual union
select 'B-1-12'   from dual union
select 'B-10-1'   from dual union
select 'B-10-100' from dual;


SQL

--■■■正規表現を使わない方法■■■
select Val
from ThreeTable
order by substr(Val,1,1),
to_number(substr(substr(Val,3),1,
          decode(instr(substr(Val,3),'-'),
                 0,Length(substr(Val,3)),
                 instr(substr(Val,3),'-')-1))),
to_number(Replace(substr(Val,3),'-'));

--■■■正規表現を使う方法(10g以降)■■■
select Val
from ThreeTable
order by substr(Val,1,1),
to_number(RegExp_Replace(Val,'^.{2}([0-9]+).*$','\1')),
to_number(Replace(substr(Val,3),'-'));


解説

Oracle10gの正規表現は、肯定戻り読みと肯定先読みをサポートしていないので、
正規表現を使う方法では、RegExp_Replace関数を使う必要があるみたいです。