2009-12-03 76 views
0

如何比较的元组组SQL:请看下面的例子:如何比较的元组组SQL

TABLE T1 
-------- 
GROUP  VALUE 
-----  ----- 
A   FOO 
A   BAR 
X   HHH 
X   ZOO 

TABLE T2 
-------- 
GROUP  VALUE 
-----  ----- 
B   ZOO 
C   FOO 
C   BAR 

我想写一个SQL查询其值的组比较表和报告,差异。在所示的示例中,即使组名不同,但是表a中的组((A,FOO),(A,BAR))与组((C,FOO),(C,BAR) 。重要的是该组的内容是相同的。最后,查询会报告有区别:它是(B,ZOO)元组。

RESULT 
------ 
GROUP  VALUE 
-----  ----- 
B   ZOO 
X   HHH 
X   ZOO 

虽然含有ZOO在T1中的基团X具有T2的匹配值:(B,ZOO)它仍然不匹配,因为该组还具有(X,HHH)值不的一部分的(B,ZOO)T2组

T1和T2(两个表)之间
+0

应该输出什么?只是一个不同的团体名单?或者差异本身? – 2009-12-03 17:08:22

+0

输出并不重要,重要的是查询会看到这些组并将它们作为组进行比较。 – paweloque 2009-12-03 17:10:12

+1

当您发布问题时,请向我们展示样品数据,清楚列出样品结果并加以标记,以便我们可以轻松帮助您。 – JonH 2009-12-03 17:16:49

回答

1

像这样的事情

create table t1 (group_id varchar2(20), value varchar2(20)); 
create table t2 (group_id varchar2(20), value varchar2(20)); 

insert into t1 values ('A','FOO'); 
insert into t1 values ('A','BAR'); 
insert into t1 values ('X','HHH'); 
insert into t1 values ('X','ZOO'); 
insert into t2 values ('C','FOO'); 
insert into t2 values ('C','BAR'); 
insert into t2 values ('B','ZOO'); 


select t1.group_id t1_group,t2.group_id t2_group, 
     --t1.all_val, t2.all_val, 
     case when t1.all_val = t2.all_val then 'match' else 'no match' end coll_match 
from 
    (select 'T1' tab_id, group_id, collect(value) all_val, 
      min(value) min_val, max(value) max_val, count(distinct value) cnt_val 
    from t1 group by group_id) t1 
full outer join 
    (select 'T2' tab_id, group_id, collect(value) all_val, 
      min(value) min_val, max(value) max_val, count(distinct value) cnt_val 
    from t2 group by group_id) t2 
on t1.min_val = t2.min_val and t1.max_val = t2.max_val and t1.cnt_val = t2.cnt_val 
/

我已经做基础上,minmium,最大和各组不同的值,这将与大型数据集帮助数的初步消除。如果数据集足够小,则可能不需要它们。

告诉你比赛。你只需要推出一个额外的步骤来找到没有任何匹配的组

select t1_group 
from 
(
    select t1.group_id t1_group,t2.group_id t2_group, 
     --t1.all_val, t2.all_val, 
     case when t1.all_val = t2.all_val then 'match' end coll_match 
    from 
    (select 'T1' tab_id, group_id, collect(value) all_val 
    from t1 group by group_id) t1 
    cross join 
    (select 'T2' tab_id, group_id, collect(value) all_val 
    from t2 group by group_id) t2 
) 
group by t1_group 
having min(coll_match) is null 
/

select t2_group 
from 
(
    select t1.group_id t1_group,t2.group_id t2_group, 
     --t1.all_val, t2.all_val, 
     case when t1.all_val = t2.all_val then 'match' end coll_match 
    from 
    (select 'T1' tab_id, group_id, collect(value) all_val 
    from t1 group by group_id) t1 
    cross join 
    (select 'T2' tab_id, group_id, collect(value) all_val 
    from t2 group by group_id) t2 
) 
group by t2_group 
having min(coll_match) is null 
/
+0

我没有看到完全的,你使用最小/最大/计数值是什么? – paweloque 2009-12-03 22:26:26

+0

如果你有一个很大的数据集(数十/数十万行),将table1中的每个组与table2中的每个组进行比较将是一项艰巨的任务。通过快速排除具有不同数量成员或具有不同最小/最大值的组,可以将最小/最大/计数降低到更易于管理的水平。 – 2009-12-03 23:39:39

+0

如果最小/最大/计数值对于一个组是相同的,但是组有所不同? – paweloque 2009-12-04 08:03:05

0

差异可能是这样的:

SELECT 
    T1.GROUPNAME, 
    T1.VALUE 
FROM 
    T1 
LEFT JOIN T2 
ON T2.Value = T1.Value 
WHERE T2.GROUPNAME IS NULL 

例如T1具有:

美孚100 酒吧200 ZZZ 333

和T2包括: 美孚100 酒吧200

该查询的结果是ZZZ 333它是不两个表中匹配的唯一记录。你甚至可以改变T2的组名说:

XYZ 100 ZXZ 200

,结果是仍然ZZZ 333这是每个你所要求的,如果你想给它的对面,你既可以UNION ,或者使用RIGHT加入。

乔恩

+0

其实我很在乎T2中的值是同一组的一部分。 – paweloque 2009-12-03 17:32:58

+0

我不明白你在问什么。再次为所有表/模式提供DDL。提供良好的样本数据和预期结果。你认为T2中的数值是否属于同一组的一部分?评论中有人问你关于团体名称的问题,你说在这两个表格中它们的值是匹配的,所以它们并不重要。我的查询处理。 – JonH 2009-12-03 17:39:52