由于题主需要动态对比,我们先做一个简单的测试。这个想法是显示不带引号的原始列以及与逗号字符串中的任何值匹配的连接中的值
SQL> create table t ( id number generated always as identity start with 1 increment by 1 , codes number ) ;
Table created.
SQL> insert into t ( codes ) values ( 201 ) ;
1 row created.
SQL> insert into t ( codes ) values ( 601 ) ;
1 row created.
SQL> insert into t ( codes ) values ( 309 ) ;
1 row created.
SQL> insert into t ( codes ) values ( 501 ) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> select * from t ;
ID CODES
---------- ----------
1 201
2 601
3 309
4 501
SQL> create table x ( codes varchar2(20) ) ;
Table created.
SQL> insert into x values ( q'('201,601')' ) ;
1 row created.
SQL> insert into x values ( q'('309,501')') ;
1 row created.
SQL> commit ;
Commit complete.
SQL> select * from x ;
CODES
--------------------
'201,601'
'309,501'
SQL> with z ( lvl , codes )
as
( select level lvl, regexp_substr ( codes, '[^,]+', 1, LEVEL) as codes
from ( select replace(codes,'''','') as codes from x )
connect by level <= regexp_count (codes, ',') + 1
)
select t.id , t.codes from t
where t.codes in ( select z.codes from z );
ID CODES
---------- ----------
1 201
2 601
4 501
3 309
同一行中的原始列不带引号
SQL> with z ( lvl , codes )
as
( select level lvl, regexp_substr ( codes, '[^,]+', 1, LEVEL) as codes
from ( select replace(codes,'''','') as codes from x )
connect by level <= regexp_count (codes, ',') + 1
)
select t.id , t.codes , replace(x.codes,'''','') as org_val
from t cross join x
where t.codes in ( select z.codes from z )
and
( t.codes like '%' || regexp_substr(replace(x.codes,'''',''),'[^,]+',1,1) || '%'
or
t.codes like '%' || regexp_substr(replace(x.codes,'''',''),'[^,]+',1,2) || '%'
);
ID CODES ORG_VAL
---------- ---------- --------------------
1 201 201,601
2 601 201,601
4 501 309,501
3 309 309,501