我有三张桌子; 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
记录,它们共同构成一个层次结构。
显示的样本数据:
d_algo_ope
没有算法或id_algo = 1
记录,d_algo_maj
没有id_algo = 300
记录。d_algo_maj
记录id_algo = 301
(足以使has_maj
列设为1)。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 :(得分:1)
如果我了解您正在做什么以及您的牌桌之间的联系,那么我认为您可以使用recursive subquery factoring获得所需的结果(假设您已经使用11gR2或更高版本):< / p>
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
CTE有一个锚点成员,它将d_algorithme
行外部连接到d_algo_maj
,并使用decode在该级别生成一个标记,或者为零或一个。那部分运行自己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
但如果您的样本数据中显示的级别超过您的水平,则递归递送。
通过为每个ID /版本找到聚合max(has_maj)
来组合它们意味着任何级别的匹配主要记录都会给出整体标记值1,如果根本没有匹配则只得到0 - 只有带有此数据的ID 300才会发生。