, ( WITH), Oracle 11.2. Oracle , - PL/SQL.
LHS, . , , REGEXP_LIKE ( , NULL). , , ; , UNM ( "unmatched" ).
, LHS , RHS, . NULL ( , ).
, - , .
with
inputs ( lhs, rhs ) as (
select 'LTD' ,'LIMITED' from dual union all
select 'LDT' ,'LIMITED' from dual union all
select 'AUSTIN','ADVERTISING' from dual union all
select 'ADP' ,'ADVANCED' from dual union all
select 'ALPHA' , null from dual union all
select null ,'BETA' from dual
),
r ( lvl, lhs, rhs, unm, pattrn, next_letter ) as (
select 1, lhs, rhs, null, null, substr(lhs, 1, 1)
from inputs
union all
select lvl + 1, lhs, rhs,
unm || case when regexp_like(rhs, pattrn || '.*' || next_letter)
then null else next_letter end,
pattrn || case when regexp_like(rhs, pattrn || '.*' || next_letter)
then '.*' || next_letter end,
substr(lhs, lvl + 1, 1)
from r
where next_letter is not null
)
cycle lvl set cycle to 1 default 0
select lhs, rhs, unm
from r
where next_letter is null
;
( ):
LHS RHS UNM
------ ----------- -----
BETA
LTD LIMITED
LDT LIMITED T
ADP ADVANCED P
ALPHA ALPHA
AUSTIN ADVERTISING UT
. , . , r
.
select *
from r
order by lhs, lvl
;
THAT.
. , , . (INSTR SUBSTR), , . , , , , ( ); RHS , .
with
inputs ( lhs, rhs ) as (
select 'LTD' ,'LIMITED' from dual union all
select 'LDT' ,'LIMITED' from dual union all
select 'AUSTIN','ADVERTISING' from dual union all
select 'ADP' ,'ADVANCED' from dual union all
select 'ALPHA' , null from dual union all
select null ,'BETA' from dual
),
r ( lhs, rhs, next_letter, unm, new_lhs, new_rhs ) as (
select lhs, rhs, substr(lhs, 1, 1), null, lhs, rhs
from inputs
union all
select lhs, rhs, substr(new_lhs, 2, 1),
unm || case when nvl(instr(new_rhs, next_letter), 0) = 0
then next_letter end,
substr(new_lhs, 2),
substr(new_rhs, nvl(instr(new_rhs, next_letter), 0) + 1)
from r
where next_letter is not null
)
cycle new_lhs set cycle to 1 default 0
select lhs, rhs, unm
from r
where next_letter is null
;