通过加入避免结合?

时间:2009-12-15 23:44:15

标签: sql join union push predicate

我的问题出在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

以下作品: (a)中

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;

2 个答案:

答案 0 :(得分:2)

我没有更多的Oracle实例,但确实尝试过PostgreSQL,这可能会引起人们的兴趣吗?

我对PostgreSQL的实验表明,工会实际上效果更好。我根据你的联合查询创建了一个视图,postgres能够将诸如“cb BETWEEN 12 AND 27”之类的谓词推送到aa和bb的扫描中。

通过对比,我创建了一个使用连接的视图:

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'

现在的问题是coalesce()阻止了一个涉及cb被推入aa和bb扫描的谓词。

答案 1 :(得分: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

您可以通过这种方式添加任意数量的表。

至于你的第三个问题,总会有更好的方法。问题是,这种方式是否足够?如果没有,您能定义可接受解决方案的要求吗?