Избегать объединения путем присоединения? - PullRequest
2 голосов
/ 16 декабря 2009

Моя проблема в Oracle, но, вероятно, она не зависит от базы данных (?).

У меня есть следующие таблицы:

аа

vid   cb
---   --
  1   10
  2   15

бб

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

(б)

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 ]

2 голосов
/ 16 декабря 2009

У меня больше нет экземпляра Oracle, но я пробовал что-то с PostgreSQL, что может быть интересно в любом случае?

Мой эксперимент с PostgreSQL показывает, что на самом деле объединение работает лучше. Я создал представление на основе вашего запроса объединения, и postgres смог вставить предикат, такой как «cb BETWEEN 12 И 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.

0 голосов
/ 16 декабря 2009

A 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

Таким способом вы можете добавить произвольное количество таблиц.

Что касается вашего третьего вопроса, всегда есть лучший способ. Вопрос в том, достаточно ли этого пути? Если нет, то можете ли вы определить требования для приемлемого решения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...