0

3 つのテーブルがあります。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 

最初の 2 つの列は からd_algorithmeのもので、 でhas_maj直接または間接的に参照されるアルゴリズムがあるかどうかに応じて、0 または 1 になりd_algo_majます。d_algo_ope間接参照は、一緒に階層を形成する1 つ以上のレコードを介して行われます。

表示されているサンプル データの場合:

  • 300: のアルゴリズムまたはd_algo_opeレコードがなく、 のレコードid_algo = 1もありません。d_algo_majid_algo = 300
  • 301: (列を 1 に設定するのに十分な) のd_algo_majレコードがあります。id_algo = 301has_maj
  • 302: のd_algo_majレコードはありませんid_algo = 302。ただし、 withと withのd_algo_opeレコードがあり、これは 302 アルゴリズムが 301 アルゴリズム ( を含む) を参照しているため、列を 1 に設定する必要があることを意味します。num_operation = 301id_algo = 302majhas_maj

これが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');
4

1 に答える 1

1

あなたが何をしているのか、そしてあなたのテーブル間のリンクを理解していれば、再帰サブクエリファクタリングであなたが望む結果を得ることができると思います(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

CTE には、行をrに外部結合するアンカー メンバーがあり、decode を使用してそのレベル、または 0 または 1 でフラグを生成します。独自に実行されるその部分は次のようになります。d_algorithmed_algo_maj

   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 でのみ発生します。 .

于 2015-05-11T17:50:58.013 に答える