比较组具有相同的绑定键

时间:2016-08-22 03:33:59

标签: sql oracle

我在2个不同的表中有如下样本。我必须编写一个sql来比较相同的源键绑定在一起。两个表中的绑定键都不匹配。

在下面的例子中,在表1中有3个绑定键1,2和& 3.装订键1有3个成员连接ABC,XYZ和& QBC。类似地绑定密钥2& 3每个都有2个源键连接到它们。

在表2中,绑定密钥99具有相同的3个密钥,它们与表1相同(计数和密钥相同),而绑定密钥78具有与表1的绑定密钥2相同的计数,但它们的源密钥是不同的。绑定密钥64具有1个源密钥,绑定密钥65具有1。

table 1:
============================== 
Binding Key|source Key 
1|ABC 
1|XYZ 
1|QBC 
2|xxx 
2|yyy 
3|uuu 
3|ddd

Table 2:
==========================
Binding Key|source Key
99|XYZ
99|QBC
99|ABC
78|xxx
78|QQQ
64|uuu
65|ddd

预期输出是识别与计数或源密钥成员不匹配的组。

Expected Output:
===========================
xxx 
yyy 
uuu 
ddd
QQQ

非常感谢!!

2 个答案:

答案 0 :(得分:1)

我找到了解决方案。它借助于listagg函数来连接同一组中的字符串然后进行比较。示例sql如下所示。

>  SELECT * FROM   (SELECT grp ,
>     ListAgg( elmnt, ',' ) within GROUP (   ORDER BY pos) AS list   FROM table1   GROUP BY grp   ) table1 WHERE table1.list NOT IN  
> (SELECT ListAgg( elmnt, ',' ) within GROUP (   ORDER BY pos) AS list  
> FROM table2   GROUP BY grp   ) UNION SELECT * FROM   (SELECT grp ,
>     ListAgg( elmnt, ',' ) within GROUP (   ORDER BY pos) AS list   FROM table2   GROUP BY grp   ) table1 WHERE table1.list NOT IN  
> (SELECT ListAgg( elmnt, ',' ) within GROUP (   ORDER BY pos) AS list  
> FROM table1   GROUP BY grp   ) ;

答案 1 :(得分:0)

此查询提供所需的输出:

with t1 as ( select row_number() over (partition by grp order by elmnt) pos, 
                    grp, elmnt from table1 ),
     t2 as ( select row_number() over (partition by grp order by elmnt) pos, 
                    grp, elmnt from table2 ),
     tx1 as (select pos, grp grp1, elmnt, 
                    listagg(elmnt, ',') within group (order by pos) 
                                        over (partition by grp) list
               from t1),
     tx2 as (select pos, grp grp2, elmnt, 
                    listagg(elmnt, ',') within group (order by pos) 
                                        over (partition by grp) list
               from t2)
select distinct elmnt 
  from (select * from tx1 full join tx2 using (list, elmnt))
  where grp1 is null or grp2 is null;

您可以轻松将其更改为显示列表,只需将distinct elmnt替换为distinct list即可。您的答案与我的查询之间的差异在于分析版本中的listagg,并且已过滤full join而不是union并结合了两个not in子句。 前两个子查询(t1t2)只会添加pos列,而原始问题中没有这些列;-)也许这也可以通过minus运算符完成。

测试数据和输出:

create table table1 (grp number(3), elmnt varchar2(5));
insert into table1 values (1, 'ABC');
insert into table1 values (1, 'XYZ');
insert into table1 values (1, 'QBC');
insert into table1 values (2, 'xxx');
insert into table1 values (2, 'yyy');
insert into table1 values (3, 'uuu');
insert into table1 values (3, 'ddd');

create table table2 (grp number(3), elmnt varchar2(5));
insert into table2 values (99, 'XYZ');
insert into table2 values (99, 'QBC');
insert into table2 values (99, 'ABC');
insert into table2 values (78, 'xxx');
insert into table2 values (78, 'QQQ');
insert into table2 values (64, 'uuu');
insert into table2 values (65, 'ddd');

ELMNT
-----
uuu
QQQ
yyy
ddd
xxx