0

2 つの同様のテーブル階層があります。

Owner -> OwnerGroup -> Parent

Owner2 -> OwnerGroup2

一連の値に基づいて、Owner2 に存在する所有者が完全に一致するかどうかを判断したいと思います。各 Owner テーブルには、約 100 万行あります。一部の OwnerGroup には、最大 100 の所有者が含まれます。

したがって、基本的に、所有者「スミス」、「ジョン」、および「スミス、ジェーン」を含む所有者グループがある場合、完全に一致する所有者グループ2のIDを知りたいです。

これに対する最初の試みは、所有者ごとに結合を生成することでした (これには、アプリケーションで動的 SQL を生成する必要がありました。

select og.id
from owner_group2 og
-- dynamic bit starts here
join owner2 o1 on
(og.id = o1.og_id) AND
(o1.given_names = 'JOHN' and o1.surname='SMITH')
-- dynamic bit ends here
join owner2 o2 on
(og.id = o2.og_id) AND
(o2.given_names = 'JANE' and o2.surname='SMITH');

これは所有者が少数になるまでは問題なく機能しますが、グループ シナリオで 100 人の所有者を処理する必要がある場合、このクエリ プランは 100 個のネストされたループが存在することを意味し、実行にほぼ 1 分かかります。

私が持っていた別のオプションは、intersectオペレーターの周りに何かを使用することでした. 例えば

select * from ( 
select o.surname, o.given_names
from owner1 o1
join owner_group1 og1 on o1.og_id = og1.id 
where 
og1.parent_id = 1936233
)
intersect
select o.surname, o.given_names
from owner2 o2 
join owner_group2 og2 on og2.id = o2.og_id;

このシナリオで owner2.id を吸い出す方法もわかりません-それでも4〜5秒の範囲で実行されていました。

明らかな何かが欠けているように感じます-より良い解決策を自由に提供してください!

4

1 に答える 1

0

で正しい軌道に乗っていますintersect。もう少し先に進む必要があります。owner_groups2ID を見つけるには、その結果をテーブルに結合する必要があります。

このlistagg関数を使用して、グループを名前のコンマ区切りリストに変換できます (注 - 11g が必要です)。次に、これらの名前リストの共通部分を取得して一致するものを見つけ、これを のリストに結合できますowner_groups2

以下に簡単な例を作成しました。「Dave、Jill」は、両方のテーブルに存在するグループです。

create table grps (id integer, name varchar2(100));
create table grps2 (id integer, name varchar2(100));

insert into grps values (1, 'Dave');
insert into grps values(1, 'Jill');

insert into grps values (2, 'Barry');
insert into grps values(2, 'Jane');

insert into grps2 values(3, 'Dave');
insert into grps2 values(3, 'Jill');

insert into grps2 values(4, 'Barry');

with grp1 as (
 SELECT id, listagg(name, ',') within group (order by name) n 
 FROM grps
 group by id
), grp2 as (
 SELECT id, listagg(name, ',') within group (order by name) n 
 FROM grps2
 group by id
)
SELECT * FROM grp2 
where  n in (
  -- find the duplicates
  select n from grp1 
  intersect
  select n from grp2
);

これにはowner_groups2;のフル スキャンが必要であることに注意してください。これを回避する方法が思いつきません。したがって、クエリは遅くなる可能性があります。

于 2013-02-04T13:01:57.373 に答える