我的问题出在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;
答案 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
您可以通过这种方式添加任意数量的表。
至于你的第三个问题,总会有更好的方法。问题是,这种方式是否足够?如果没有,您能定义可接受解决方案的要求吗?