2009-12-15 64 views
2

我的問題是在Oracle上,但可能與數據庫無關(?)。通過加入避免結合?

我有以下表格:

AA

vid cb 
--- -- 
    1 10 
    2 15 

BB

vid cb 
--- -- 
    3 25 
    4 24 

**代表*

repid vid p 
----- --- -- 
    99 1 aa 
    99 2 aa 
    99 3 bb 
    99 4 bb 

列p指示要在哪個表中獲取該行。 實際上,aa和bb有更多不同,p與表名不匹配,但給出了一種實現方式。這個例子只是一個簡單的問題。 注意事實上,有超過2個表aa和bb(有6個)。 我想返回的查詢:

repid vid p cb 
----- --- -- -- 
    99 1 aa 10 
    99 2 aa 15 
    99 3 bb 25 
    99 4 bb 24 

以下工作: (一)

select rep.vid, rep.p, cb 
from (
select 'aa' as p,vid,cb from aa 
union all 
select 'bb' as p, vid,cb from bb) u,rep 
where rep.p=u.p and rep.vid=u.vid 

(B)

select rep.vid, rep.p, 
    decode(rep.p, 'aa', (select cb from aa where vid=rep.vid), 
       'bb', (select cb from bb where vid=rep.vid)) cb 
from rep 

但我想使用該查詢一種觀點,其中可以有謂詞推動。

所以問題1是:以下是否允許謂詞推送。 問題2 :(即使問題1是)有沒有辦法做到這一點沒有工會,但與聯合。 問題3:或者僅僅是一種更好的方式?

腳本來創建數據:

create table bb (vid number(1), cb number(2)); 
create table aa (vid number(1), cb number(2)); 
create table rep(rid number(2), vid number(1), p varchar2(2)); 
insert into rep (rid,vid,p) values (99, 4,'bb'); 
insert into rep (rid,vid,p) values (99, 3,'bb'); 
insert into rep (rid,vid,p) values (99, 2,'aa'); 
insert into rep (rid,vid,p) values (99, 1,'aa'); 
insert into bb (vid,cb) values (4,24); 
insert into bb (vid,cb) values (3,25); 
insert into aa (vid,cb) values (2,15); 
insert into aa (vid,cb) values (1,10); 
commit; 
+0

你對模式有控制嗎?我認爲你不能改變任何表格? – Burt 2009-12-15 23:52:00

+0

正確:表已存在,我無法更改它們。 – 2009-12-16 09:48:42

回答

0

join可以指定多個條件。表名可以是一個。例如,如果table1有一個名爲TableName列引用其他表,你可以使用:

select  * 
from  table1 t1 
left join table2 t2 
on   t1.TableName = 'table2' 
      and t1.id = t2.id 
left join table3 t3 
on   t1.TableName = 'table3' 
      and t1.id = t3.id 

您可以添加表的這樣一個任意號碼。

至於你的第三個問題,總有一個更好的辦法。問題是,這樣做足夠嗎?如果不是,您能否定義可接受解決方案的要求?

+0

是的,如果這些表有一個名爲tableName的列,那肯定會有所幫助。問題是他們沒有。我想一個解決方案是創建這些表的視圖,幷包括tableName(或等效)。 – 2009-12-16 10:17:51

+0

@Nicolas:你的表「rep」包含一個帶有表名的字段「pp」? – Andomar 2009-12-16 10:22:18

+0

其實,你會有什麼,而不是*具有table1的列cb或table2的cb取決於p的值。 這是問題的重要部分:「合併」來自不同表格的列。 – 2009-12-16 10:29:13

2

我沒有Oracle實例可以繼續使用,但是嘗試過使用PostgreSQL,無論如何可能會引起興趣?

我對PostgreSQL的實驗表明,實際上聯合效果更好。我根據你的聯合查詢創建了一個視圖,並且postgres能夠將諸如「cb BETWEEN 12和27」之類的謂詞推送到aa和bb的掃描中。

通過constrast,我創建了一個使用連接的視圖:

create view rep2 as 
    select rep.vid, p, coalesce(aa.cb, bb.cb) as cb 
    from rep 
     left join aa on aa.vid = rep.vid and rep.p = 'aa' 
     left join bb on bb.vid = rep.vid and rep.p = 'bb' 

現在的問題是,所述聚結()塊涉及CB謂詞被推入aa和bb的掃描。