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

4-7 文字を順番にセット

SQLパズル

会員テーブル
会員番号   電話番号
--------  ------------
12345678  -1-1-1-1-1-1
12345678  333-333-4444
12345678  22-4444-4444
12345678  4444-333-333
12345678  -55555-4444-
12345678  -88888888-22

会員番号を、電話番号の数字部分に順番にセットする。

出力結果
会員番号    マスク前      マスク後
--------  ------------  ------------
12345678  -1-1-1-1-1-1  -1-2-3-4-5-6
12345678  333-333-4444  123-456-7812
12345678  22-4444-4444  12-3456-7812
12345678  4444-333-333  1234-567-812
12345678  -55555-4444-  -12345-6781-
12345678  -88888888-22  -12345678-12
こちらを参考にさせていただきました


データ作成スクリプト

create table 会員(
会員番号 char(8),
電話番号 char(12));

insert into 会員 values('12345678','-1-1-1-1-1-1');
insert into 会員 values('12345678','333-333-4444');
insert into 会員 values('12345678','22-4444-4444');
insert into 会員 values('12345678','4444-333-333');
insert into 会員 values('12345678','-55555-4444-');
insert into 会員 values('12345678','-88888888-22');
commit;


SQL

col マスク前 for a15
col マスク後 for a15

--■■■model句と正規表現を使う方法(10g以降)■■■
select 会員番号,マスク前,マスク後
  from 会員
 model
partition by (RowNum as PID)
dimension by (0 as soeji)
measures(会員番号,電話番号 as マスク前,電話番号 as マスク後)
rules ITERATE (100)
(
マスク後[0] =
case when RegExp_Instr(マスク後[0],'[0-9]',1,ITERATION_NUMBER+1) > 0
     then RegExp_Replace(マスク後[0],'[0-9]',
                         substr(会員番号[0],case when mod(ITERATION_NUMBER+1,length(会員番号[0])) = 0
                                                 then length(会員番号[0])
                                                 else mod(ITERATION_NUMBER+1,length(会員番号[0])) end,1),
                         RegExp_Instr(マスク後[0],'[0-9]',1,ITERATION_NUMBER+1),1)
     else マスク後[0] end)
order by マスク前;

--■■■case式を多用する方法■■■
select 会員番号,電話番号 as マスク前,
case when substr(電話番号,1,1) = '-' then '-'
else substr(会員番号,1,1) end ||
case when substr(電話番号,2,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,2),'-')),1) end ||
case when substr(電話番号,3,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,3),'-')),1) end ||
case when substr(電話番号,4,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,4),'-')),1) end ||
case when substr(電話番号,5,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,5),'-')),1) end ||
case when substr(電話番号,6,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,6),'-')),1) end ||
case when substr(電話番号,7,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,7),'-')),1) end ||
case when substr(電話番号,8,1) = '-' then '-'
else substr(会員番号,Length(replace(substr(電話番号,1,8),'-')),1) end ||
case when substr(電話番号,9,1) = '-' then '-'
else substr(会員番号 || 会員番号,Length(replace(substr(電話番号,1,9),'-')),1) end ||
case when substr(電話番号,10,1) = '-' then '-'
else substr(会員番号 || 会員番号,Length(replace(substr(電話番号,1,10),'-')),1) end ||
case when substr(電話番号,11,1) = '-' then '-'
else substr(会員番号 || 会員番号,Length(replace(substr(電話番号,1,11),'-')),1) end ||
case when substr(電話番号,12,1) = '-' then '-'
else substr(会員番号 || 会員番号,Length(replace(電話番号,'-')),1) end as マスク後
from 会員;


解説

1文字ずつ、case式でハイフンかチェックして分岐させてます。
model句を使ってもいいでしょう。