2013-02-04 24 views
0

我有兩個類似的表層次:匹配兩個相似的表之間的一組子記錄層次結構

Owner -> OwnerGroup -> Parent 

Owner2 -> OwnerGroup2 

我想,以確定是否有業主的精確匹配基於一組值,存在於Owner2中。每個Owner表中大約有一百萬行。某些所有者組包含多達100個所有者。

所以基本上,如果有比包含業主「史密斯」,「約翰」和OwnerGroup「史密斯,‘簡’,我想知道,是完全匹配的OwnerGroup2s的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個嵌套循環,並且需要幾分鐘的時間才能運行。

我的另一個選擇是使用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秒範圍內運行。

我覺得我缺少一些明顯的東西 - 所以請隨時提供一些更好的解決方案!

回答

0

你正處於正確的軌道上,intersect,你只需要進一步。您需要將其結果返回到owner_groups2表中以查找ID。

您可以使用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;我想不出一種可以避免這種情況的方法。所以你的查詢可能會保持緩慢。

相關問題