0

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

T1 に ZOO を含むグループ X は T2 に一致する値 (B,ZOO) を持っていますが、グループは (B, ZOO) グループの一部ではない (X, HHH) 値も持っているため、まだ一致していません。 T2で

4

2 に答える 2

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
/

大規模なデータセットに役立つ、各グループの個別の値の最小値、最大値、および数に基づいて予備的な除去を行いました。データセットが十分に小さい場合は、必要ない場合があります。

それはあなたに一致を教えてくれます。一致するグループがないグループを見つけるには、追加の手順を実行する必要があります。

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
/
于 2009-12-03T22:12:58.467 に答える
0

T1 と T2 (2 つのテーブル) の違いは次のとおりです。

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 には以下が含まれます: Foo 100 Bar 200

そのクエリの結果は ZZZ 333 で、両方のテーブルで一致しない唯一のレコードです。T2 のグループ名を次のように変更することもできます。

XYZ 100 ZXZ 200

結果はまだ ZZZ 333 です。これは、あなたが求めているとおりです。逆にしたい場合は、UNION するか、RIGHT Join を使用できます。

ジョン

于 2009-12-03T17:30:26.183 に答える