Oracle присоединяется к любому из нескольких столбцов - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть таблица RELATION

NUM1 | NUM2 | NUM3
 --   ---   -----
 1     2     3    
 2     4     5
 3     4     null
 3     4     null

и фактическая таблица INFO, где NUM является первичным ключом.

 NUM | A_LOT_OF_OTHER_INFO
 ---  --------------------
   1     asdff    
   2     werwr
   3     erert
   4     ghfgh
   5     cvbcb

Я хочу создать представление, чтобы увидеть счетчик NUMкоторый появился в любом из NUM1, NUM2, NUM3 таблицы RELATION.

MY_VIEW

 NUM | A_LOT_OF_OTHER_INFO | TOTAL_COUNT
 ---  --------------------  ------------
   1     asdff                  1
   2     werwr                  2
   3     erert                  3
   4     ghfgh                  3
   5     cvbcb                  1

Я могу сделать это, сделав три выбора из таблицы RELATION и UNION их, но я не хочу использовать UNION, потому что в таблицах много записей, MY_VIEWуже достаточно большой, и я ищу лучший способ присоединиться к таблице RELATION в представлении.Можете ли вы предложить способ?

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

Кажется, что вы хотите, это UNPIVOT.Возможно, в этом случае проще всего сделать перекрестное соединение:

select   NUM, count(*) as TOTAL_COUNT
from     ( 
           select decode(column_value, 1, NUM1, 2, NUM2, 3, NUM3) as NUM
           from   RELATION cross join table(sys.odcinumberlist(1,2,3))
         )
group by NUM
;

Затем соедините это со второй таблицей;часть соединения здесь действительно неактуальна.

0 голосов
/ 29 ноября 2018

Я бы попытался отменить поворот таблицы отношений.

После этого объединить информационную таблицу со значениями и посчитать, сколько раз повторяется val.

create table relation(num1 int,num2 int, num3 int);

insert into relation values(1,2,3);
insert into relation values(2,4,5);
insert into relation values(3,4,null);

create table info(num int, a_lot_of_other_info varchar2(100));
insert into info
   select 1,'asdff' from dual union all
   select 2,'werwr' from dual union all
   select 3,'erert' from dual union all
   select 4,'ghfgh' from dual union all
   select 5,'cvbcb' from dual 

 select a.num
        ,max(a_lot_of_other_info) as a_lot_of_other_info
        ,count(*) as num_of_times
   from info a
   join (select val
           from relation a
         unpivot(val for x in (num1,num2,num3))
         )b
      on a.num=b.val  
 group by a.num 
 order by 1
0 голосов
/ 29 ноября 2018

Я хотел бы предложить коррелированный подзапрос:

select i.*,
       (select ((case when r.num1 = i.num then 1 else 0 end) +
                (case when r.num2 = i.num then 1 else 0 end) +
                (case when r.num3 = i.num then 1 else 0 end)
               )
        from relation r
        where i.num in (r.num1, r.num2, r.num3)
       ) as total_count
from info i;

Если производительность имеет значение, может быть быстрее использовать left join s:

select i.*,
       ((case when r1.num1 is not null then 1 else 0 end) +
        (case when r2.num1 is not null then 1 else 0 end) +
        (case when r3.num1 is not null then 1 else 0 end)
       ) as total_count
from info i left join
     relation r1
     on i.num = r1.num1 left join
     relation r2
     on i.num = r2.num2 left join
     relation r3
     on i.num = r3.num3;

В частности, это будетоптимально использовать три отдельных индекса для relation: relation(num1), relation(num2) и relation(num3).

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