Oracle SQL 2逗号分隔字符串的交集

时间:2019-05-13 06:31:39

标签: sql regex oracle

我可以用作功能吗?

查询:

Select x, f(y) from table where y like '%ab%cd%ef';

样本表( y 按字母顺序排序)

x.  y
1   ab
2   ab,cd
3   cd,ef
4   ab,ef,gh,yu
5   de,ef,rt

预期输出:

输出:

x y
1 ab
2 ab,cd
3 cd,ef
4 ab,ef
5 ef

2 个答案:

答案 0 :(得分:1)

regexp_substr函数与connect by level表达式一起使用

with tab(x,y) as
(
 select 1,'ab'          from dual union all
 select 2,'ab,cd'       from dual union all
 select 3,'cd,ef'       from dual union all 
 select 4,'ab,ef,gh,yu' from dual union all 
 select 5,'de,ef,rt'    from dual
), tab2 as
( 
Select x, regexp_substr(y,'[^,]+',1,level) as y 
  from tab  
 connect by level <= regexp_count(y,',') + 1 
     and prior x = x
     and prior sys_guid() is not null
), tab3 as
(
select x, y  
  from tab2     
 where y like '%ab%'
    or y like '%cd%'
    or y like '%ef%'
)
select x, listagg(y,',') within group (order by y) as y 
  from tab3      
 group by x;

X   Y
1   ab
2   ab,cd
3   cd,ef
4   ab,ef
5   ef

Demo

答案 1 :(得分:1)

遵循代码中编写的注释。

SQL> with test (x, y) as
  2    -- your sample table
  3    (select 1, 'ab' from dual union all
  4     select 2, 'ab,cd' from dual union all
  5     select 3, 'cd,ef' from dual union all
  6     select 4, 'ab,ef,gh,yu' from dual union all
  7     select 5, 'de,ef,rt' from dual
  8    ),
  9  srch (val) as
 10    -- a search string, which is to be compared to the sample table's Y column values
 11    (select 'ab,cd,ef' from dual),
 12  --
 13  srch_rows as
 14    -- split search string into rows
 15    (select regexp_substr(val, '[^,]+', 1, level) val
 16     from srch
 17     connect by level <= regexp_count(val, ',') + 1
 18    ),
 19  test_rows as
 20    -- split sample values into rows
 21    (select x,
 22            regexp_substr(y, '[^,]+', 1, column_value) y
 23     from test,
 24          table(cast(multiset(select level from dual
 25                              connect by level <= regexp_count(y, ',') + 1
 26                             ) as sys.odcinumberlist))
 27    )
 28  -- the final result
 29  select t.x, listagg(t.y, ',') within group (order by t.y) result
 30  from test_rows t join srch_rows s on s.val = t.y
 31  group by t.x
 32  order by t.x;

         X RESULT
---------- --------------------
         1 ab
         2 ab,cd
         3 cd,ef
         4 ab,ef
         5 ef

SQL>