2015-05-11 6 views
0

У меня есть три таблицы; d_algorithme:Иерархический запрос с отношением один к одному

ID_ALGO VERSION_ALGO LIBELLE_ALGO          
---------- ------------ -------------------------------------------------- 
     300 A300V1  Algo_300_V1          
     301 A301V1  Algo_301_V1          
     302 A302V1  Algo_302_V1          

d_algo_ope:

NUM_OPERATION ID_ALGO VERSION_ALGO TYP_OPERATION NUM_ORDRE 
------------- ---------- ------------ ------------- ---------- 
      300  301 A301V1     3   1 
      1  300 A300V1     3   1 
      301  302 A302V1     3   1 

и, наконец, d_algo_maj:

NUM_MISE_A_JOUR ID_ALGO VERSION_ALGO 
--------------- ---------- ------------ 
      11  301 A301V1  

Я хочу, чтобы создать запрос, дающую результат, как:

id_algo | version_algo | has_maj 
300  | A300V1  | 0  
301  | A301V1  | 1 
302  | A302V1  | 1 

Если первые два столбца от d_algorithme, а has_maj - 0 или 1, в зависимости от того, существует ли прямой или косвенный алгоритм, указанный в d_algo_maj. Косвенная ссылка - это одна или несколько записей d_algo_ope, которые вместе образуют иерархию.

Для данных образцов, показанные:

  • 300: нет алгоритма или d_algo_ope записи с id_algo = 1 и нет d_algo_maj записи с id_algo = 300.
  • 301: есть запись d_algo_maj с id_algo = 301 (достаточно, чтобы сделать столбец has_maj установлен в 1).
  • 302: d_algo_maj запись с id_algo = 302. Но есть d_algo_ope запись с num_operation = 301 и id_algo = 302, что означает, что 302 алгоритм ссылается 301 алгоритм (который имеет maj) и, следовательно, has_maj столбец должен быть установлен в 1.

Вот DDL и DML и другие детали (упрощенно от того, что у меня есть на самом деле):

-- DDL ----------------------------- 

-- d_algorithme 
CREATE TABLE D_ALGORITHME 
(
    ID_ALGO NUMBER(10, 0) NOT NULL 
, VERSION_ALGO VARCHAR2(6 BYTE) NOT NULL 
, LIBELLE_ALGO VARCHAR2(50 BYTE) NOT NULL 
) ; 

ALTER TABLE D_ALGORITHME 
ADD CONSTRAINT IX_D_ALGORITHME PRIMARY KEY 
(
    ID_ALGO 
, VERSION_ALGO 
); 

-- d_algo_ope 
CREATE TABLE D_ALGO_OPE 
(
    NUM_OPERATION NUMBER(10, 0) NOT NULL 
, ID_ALGO NUMBER(10, 0) NOT NULL 
, VERSION_ALGO VARCHAR2(6 BYTE) NOT NULL 
, TYP_OPERATION NUMBER(6, 0) NOT NULL 
, NUM_ORDRE NUMBER(10, 0) NOT NULL 
); 

ALTER TABLE D_ALGO_OPE 
ADD CONSTRAINT IX_D_ALGO_OPE PRIMARY KEY 
(
    ID_ALGO 
, VERSION_ALGO 
, NUM_ORDRE 
) ; 

-- d_algo_maj 
CREATE TABLE D_ALGO_MAJ 
(
    NUM_MISE_A_JOUR NUMBER(10, 0) NOT NULL 
, ID_ALGO NUMBER(10, 0) NOT NULL 
, VERSION_ALGO VARCHAR2(6 BYTE) NOT NULL 
) 
; 

ALTER TABLE D_ALGO_MAJ 
ADD CONSTRAINT IX_D_ALGO_MAJ PRIMARY KEY 
(
    ID_ALGO 
, VERSION_ALGO 
, NUM_MISE_A_JOUR 
) 
; 


-- DML ---------------- 


REM INSERTING into D_ALGORITHME 


Insert into D_ALGORITHME (ID_ALGO,VERSION_ALGO,LIBELLE_ALGO) 
    values ('300','A300V1','Algo_300_V1'); 
Insert into D_ALGORITHME (ID_ALGO,VERSION_ALGO,LIBELLE_ALGO) 
    values ('301','A301V1','Algo_301_V1'); 
Insert into D_ALGORITHME (ID_ALGO,VERSION_ALGO,LIBELLE_ALGO) 
    values ('302','A302V1','Algo_302_V1'); 



REM INSERTING into D_ALGO_OPE 

Insert into D_ALGO_OPE 
    (NUM_OPERATION,ID_ALGO,VERSION_ALGO,TYP_OPERATION,NUM_ORDRE) 
values ('300','301','A301V1','3','1'); 
Insert into D_ALGO_OPE (NUM_OPERATION,ID_ALGO,VERSION_ALGO,TYP_OPERATION,NUM_ORDRE) 
    values ('1','300','A300V1','3','1'); 
Insert into D_ALGO_OPE (NUM_OPERATION,ID_ALGO,VERSION_ALGO,TYP_OPERATION,NUM_ORDRE) 
    values ('301','302','A302V1','3','1'); 



REM INSERTING into D_ALGO_MAJ 

Insert into D_ALGO_MAJ (NUM_MISE_A_JOUR,ID_ALGO,VERSION_ALGO) 
    values ('11','301','A301V1'); 
+0

обычного соединения может быть недостаточно для достижения этого, так как существует множество уровней, связанных третьей таблицей, которая является d_algo_ope. –

+1

Не уверен, что я понимаю, как связаны три таблицы или как они образуют иерархию. И ID/версия 1/1 и 2/2 имеют записи в d_algo_maj, так почему первый косвенный? Откуда в него входит d_algo_ope? –

+0

@AlexPoole Я надеюсь, что изображение в этих ссылках объясняет больше –

ответ

1

Если я понимаю, что вы делаете, и связь между вашими таблицами, то я думаю, что вы можете получить результат, который вы хотите с recursive subquery factoring (если вы на 11gR2 или выше):

with r (id_algo, version_algo, has_maj, last_id_algo, last_version_algo) as (
    select da.id_algo, da.version_algo, decode(dm.id_algo, null, 0, 1), 
    da.id_algo, da.version_algo 
    from d_algorithme da 
    left join d_algo_maj dm 
    on dm.id_algo = da.id_algo 
    and dm.version_algo = da.version_algo 
    union all 
    select dao.id_algo, dao.version_algo, decode(dm.id_algo, null, 0, 1), 
    dao.id_algo, dao.version_algo 
    from r 
    join d_algo_ope dao 
    on dao.id_algo = r.last_id_algo 
    and dao.version_algo = r.last_version_algo 
    left join d_algo_maj dm 
    on dm.id_algo = dao.num_operation 
) 
cycle id_algo, version_algo set is_cycle to 1 default 0 
select id_algo, version_algo, max(has_maj) as has_maj 
from r 
group by id_algo, version_algo 
order by id_algo, version_algo; 

    ID_ALGO VERSION_ALGO HAS_MAJ 
---------- ------------ ---------- 
     300 A300V1    0 
     301 A301V1    1 
     302 A302V1    1 

r КТР имеет элемент якорь, который наружный присоединяется к d_algorithme строк d_algo_maj, и использует декодирование для генерирования флага на этом уровне, или ноль или один. Та часть работать на своих собственных woud получить:

ID_ALGO VERSION_ALGO HAS_MAJ LAST_ID_ALGO LAST_VERSION_ALGO 
---------- ------------ ---------- ------------ ----------------- 
     300 A300V1    0   300 A300V1   
     301 A301V1    1   301 A301V1   
     302 A302V1    0   302 A302V1   

Рекурсивный член затем просматривает любой соответствующий d_aldo_ope запись и внешние соединения , что к d_algo_maj таким же образом, получая тот же флаг. Та часть сама по себе будет получить:

ID_ALGO VERSION_ALGO HAS_MAJ LAST_ID_ALGO LAST_VERSION_ALGO 
---------- ------------ ---------- ------------ ----------------- 
     300 A300V1    0   300 A300V1   
     301 A301V1    0   301 A301V1   
     302 A302V1    1   302 A302V1   

Но рекурсивно, если вы имели больше уровней, чем вы показали в выборочных данных.

Объединение данных путем поиска совокупности max(has_maj) для каждого идентификатора/версии означает, что соответствующая основная запись на любом уровне дает общее значение флага 1, и вы получаете только 0, если совпадений нет, что происходит только для ID 300 с этими данными.