2009-12-03 75 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