2

私の問題は Oracle にありますが、おそらくデータベースに依存していません (?)。

次のテーブルがあります。

ああ

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 はテーブル名と一致しませんが、そこに到達する方法を提供します。この例は、私が問題を抱えている単純化したものです。実際には、aa と bb の 2 つ以上のテーブル (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

(ロ)

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;
4

2 に答える 2

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() が aa と bb のスキャンにプッシュされる cb を含む述語をブロックすることです。

于 2009-12-16T00:23:51.223 に答える
0

join複数の条件を指定できます。テーブル名は 1 つです。たとえば、他のテーブルを参照する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

この方法で任意の数のテーブルを追加できます。

3 番目の質問については、常により良い方法があります。問題は、この方法で十分かどうかです。そうでない場合、受け入れ可能なソリューションの要件を定義できますか?

于 2009-12-15T23:49:19.967 に答える