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

10-167 二番目以降の数値をゼロサプレス

SQLパズル

PL/SQLで、
以下の文字列の、二番目以降のハイフン以降の数値を、
ゼロサプレスする

出力結果
----------------------------------------
before■X-00001
after ■X-00001
before■X-00001-001
after ■X-00001-1
before■X-00001-012-123
after ■X-00001-12-123
before■X-00001-00151200-000123000123000
after ■X-00001-151200-123000123000

こちらを参考にさせていただきました


SQL

declare
    procedure zeroSuppress(pstr varchar2) is
        appearCount pls_Integer := 0;
        ignoreZero boolean := false;
        willOut varchar2(4000);

        begin
            DBMS_Output.Put_Line('before■' || pstr);
            for i in 1..length(pstr) Loop
                if substr(pstr,i,1) = '-' then
                    appearCount := appearCount + 1;
                    ignoreZero := (appearCount >= 2);
                    willOut := willOut || substr(pstr,i,1);
                elsif ignoreZero and substr(pstr,i,1) = '0' then
                    null;
                else
                    ignoreZero := false;
                    willOut := willOut || substr(pstr,i,1);
                end if;
            end Loop;
            DBMS_Output.Put_Line('after ■' || willOut);
        end zeroSuppress;
begin
    zeroSuppress('X-00001');
    zeroSuppress('X-00001-001');
    zeroSuppress('X-00001-012-123');
    zeroSuppress('X-00001-00151200-000123000123000');
end;
/


解説

内部プロシージャと、boolean型は、
PL/SQLを組む上で便利です。

データによっては、このような正規表現を使ってもいいでしょう。

SQL> select Val as before,
  2  RegExp_Replace(Val,'([0-9]+-)0*','\1') as after
  3    from (select 'X-00001' as Val from dual
  4    union select 'X-00001-001' from dual
  5    union select 'X-00001-012-123' from dual
  6    union select 'X-00001-151200-123000123000' from dual);

before                     ■after
---------------------------■------------------------------
X-00001                    ■X-00001
X-00001-001                ■X-00001-1
X-00001-012-123            ■X-00001-12-123
X-00001-151200-123000123000■X-00001-151200-123000123000