如果您想使用某种逻辑加入target 和source,基于每列中列出的一组值的交集,那么最可靠的方法是将字符串拆分为集合并进行操作从前一行收集并从当前行收集来构建一棵树。
在 Oracle 中有许多技术可以从分隔的字符串中构建集合,其中一种技术说明了 in this answer to another question。
创建所需的集合类型:
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)包含分隔列表,所以我为每个列都包含。
构建集合后,可以使用multiset operators 和可用的test functions 将目标与源匹配。例如。
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 构造很有用。