PLSQL-比较两个逗号分隔并删除重复项

时间:2019-02-03 04:17:35

标签: sql oracle stringtokenizer

我在两列中有逗号分隔的值,并且我想删除两列中可用的“公用”值。下面是示例数据

col1                           col2
1234, 5623, 1236,1567          5623, 9089,1567,2890,1234
145,126,1236,1478              1748,8956,1234,1478

Required Data
COL1                           COL2
1236                           9089,2890
145,126,1236                   1748,8956,1234

谢谢

1 个答案:

答案 0 :(得分:2)

我已经稍微修改了您的表并添加了ID列,该列唯一地标识了一行,因此它看起来像这样:

SQL> select * from test;

        ID COL1                           COL2
---------- ------------------------------ ------------------------------
         1 1234, 5623, 1236,1567          5623, 9089,1567,2890,1234
         2 145,126,1236,1478              1748,8956,1234,1478

这种方法

  • 将所有列拆分为行(t_one用于col1t_two用于col2
  • inter CTE使用INTERSECT集运算符来查找应从结果中删除的公用值
  • t1_newt2_new汇总新的列值(使用LISTAGG函数)
  • 最后的SELECT返回最终结果

在这里:

SQL> with
  2  t_one as
  3    (select id,
  4            trim(regexp_substr(col1, '[^,]+', 1, column_value)) c1
  5     from test,
  6          table(cast(multiset(select level from dual
  7                              connect by level <= regexp_count(col1, ',') + 1
  8                             ) as sys.odcinumberlist))
  9    ),
 10  t_two as
 11    (select id,
 12            trim(regexp_substr(col2, '[^,]+', 1, column_value)) c2
 13     from test,
 14          table(cast(multiset(select level from dual
 15                              connect by level <= regexp_count(col2, ',') + 1
 16                             ) as sys.odcinumberlist))
 17    ),
 18  inter as
 19    (select t1.id, t1.c1 cx from t_one t1
 20     intersect
 21     select t2.id, t2.c2 cx from t_two t2
 22    ),
 23  t1_new as
 24    (select a.id, listagg(a.c1, ',') within group (order by a.c1) c1_new
 25     from (select t1.id, t1.c1 from t_one t1
 26           minus
 27           select i.id, i.cx from inter i
 28          ) a
 29     group by a.id
 30    ),
 31  t2_new as
 32    (select b.id, listagg(b.c2, ',') within group (order by b.c2) c2_new
 33     from (select t2.id, t2.c2 from t_two t2
 34           minus
 35           select i.id, i.cx from inter i
 36          ) b
 37      group by b.id
 38     )
 39  select a.id, a.c1_new, b.c2_new
 40  from t1_new a join t2_new b on a.id = b.id;

        ID C1_NEW               C2_NEW
---------- -------------------- --------------------
         1 1236                 2890,9089
         2 1236,126,145         1234,1748,8956

SQL>