如果您想加入target
并source
使用一些逻辑,基于每列中列出的一组值的交集,那么最可靠的方法是将字符串拆分为集合,并对来自前一行的集合和来自当前行的集合进行操作建造一棵树。
有许多技术可以在 Oracle 中从分隔字符串构建集合,其中一种技术在对另一个问题的回答中进行了说明。
创建所需的集合类型:
create or replace type TIdList as table of varchar2(100);
在您的情况下,内部选择如下所示:
SELECT
t.*,
(
cast(multiset( -- Convert set of values into collection
select -- Build list of values from separated string
substr(
source,
decode( level, 1, 1, instr(source,',',1,level-1)+1 ),
decode( instr(source,',',1,level), 0, length(source)+1, instr(source,',',1,level) )
-
decode( level, 1, 1, instr(source,',',1,level-1)+1 )
) code
from dual
start with source is not null
connect by instr(source,',',1,level-1) > 0
) as TIdList )
) source_id_list,
(
cast(multiset( -- Convert set of values into collection
select -- Build list of values from separated string
substr(
target,
decode( level, 1, 1, instr(target,',',1,level-1)+1 ),
decode( instr(target,',',1,level), 0, length(target)+1, instr(target,',',1,level) )
-
decode( level, 1, 1, instr(target,',',1,level-1)+1 )
) code
from dual
start with target is not null
connect by instr(target,',',1,level-1) > 0
) as TIdList )
) target_id_list
FROM bdTable t
WHERE t.parentek = t_parKey
因为我不知道哪一列 (source
或target
) 包含分隔列表,所以我为每个列添加了列。
在构建集合之后,可以使用多集运算符和可用的测试函数来匹配目标和源。例如
with inner_query as (
SELECT
t.*,
(
cast(multiset( -- Convert set of values into collection
select -- Build list of values from separated string
substr(
source,
decode( level, 1, 1, instr(source,',',1,level-1)+1 ),
decode( instr(source,',',1,level), 0, length(source)+1, instr(source,',',1,level) )
-
decode( level, 1, 1, instr(source,',',1,level-1)+1 )
) code
from dual
start with source is not null
connect by instr(source,',',1,level-1) > 0
) as TIdList )
) source_id_list,
(
cast(multiset( -- Convert set of values into collection
select -- Build list of values from separated string
substr(
target,
decode( level, 1, 1, instr(target,',',1,level-1)+1 ),
decode( instr(target,',',1,level), 0, length(target)+1, instr(target,',',1,level) )
-
decode( level, 1, 1, instr(target,',',1,level-1)+1 )
) code
from dual
start with target is not null
connect by instr(target,',',1,level-1) > 0
) as TIdList )
) target_id_list
FROM bdTable t
WHERE t.parentek = t_parKey
)
select
level lvl,
tree_list.*
from
inner_query tree_list
start with
source is null
connect by
nvl(cardinality(prior target_id_list MULTISET INTERSECT source_id_list),0) > 0
如果只有一列可以包含值列表,则MEMBER OF
构造很有用。