按多个条件加入层次结构

问题描述 投票:0回答:1

我有3个表,一个包含用户和分配给这些用户的元素。表DDL看起来像这样。

  CREATE TABLE FSECURE
   (    "USERID" VARCHAR2(100 BYTE), 
    "F_ELEMENT" VARCHAR2(6 BYTE), 
    "O_ELEMENT" VARCHAR2(20 BYTE), 
    "TYPE" VARCHAR2(20 BYTE)
   );

表包含的数据如下所示。

   REM INSERTING into FSECURE
SET DEFINE OFF;
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','140','2003','APP1');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','280','2003','APP1');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('GGA','202118','2003','APP2');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('GGA','140','2004','APP2');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('RFA','202116','3662','APP3');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','110001','3662','APP3');

fvol表包含对f_secure表的o_element列的引用。

 CREATE TABLE FVOL
       (    "ORG" VARCHAR2(6 BYTE), 
        "ORG_PRED" VARCHAR2(6 BYTE)
       );

REM INSERTING into FVOL
SET DEFINE OFF;
Insert into FVOL (ORG,ORG_PRED) values ('2003',null);
Insert into FVOL (ORG,ORG_PRED) values ('3661','2003');
Insert into FVOL (ORG,ORG_PRED) values ('3662','2003');
Insert into FVOL (ORG,ORG_PRED) values ('2009',null);
Insert into FVOL (ORG,ORG_PRED) values ('366X','2009');
Insert into FVOL (ORG,ORG_PRED) values ('366P','2009');
Insert into FVOL (ORG,ORG_PRED) values ('2004',null);
Insert into FVOL (ORG,ORG_PRED) values ('1114','2004');
Insert into FVOL (ORG,ORG_PRED) values ('2224','2004');

fval表包含对fsecure表中f_element的引用。

CREATE TABLE "FVAL" 
   (    "FUND" VARCHAR2(6 BYTE), 
    "FUND_PRED" VARCHAR2(6 BYTE)
   );



    REM INSERTING into FVAL
SET DEFINE OFF;
Insert into FVAL (FUND,FUND_PRED) values ('140',null);
Insert into FVAL (FUND,FUND_PRED) values ('280',null);
Insert into FVAL (FUND,FUND_PRED) values ('2000','140');
Insert into FVAL (FUND,FUND_PRED) values ('20001','2000');
Insert into FVAL (FUND,FUND_PRED) values ('20002','2000');
Insert into FVAL (FUND,FUND_PRED) values ('20003','2000');
Insert into FVAL (FUND,FUND_PRED) values ('202118','2000');
Insert into FVAL (FUND,FUND_PRED) values ('2800','280');
Insert into FVAL (FUND,FUND_PRED) values ('280001','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280002','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280003','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280004','2800');
Insert into FVAL (FUND,FUND_PRED) values ('110001','11000');
Insert into FVAL (FUND,FUND_PRED) values ('110002','11000');

我遇到的问题是我需要通过用户遍历层次结构 - f_element - o_element - type

因此,例如在user_id FFA的情况下,fsecure表中的层次结构节点为F_ELEMENT = '140'O_ELEMENT = '2003'和TYPE APP1,我应该检索样本输出:

FUND:     ORG:          TYPE:
20001     3661          APP1
20002     3661          APP1
20003     3661          APP1
202118    3661          AAP1

20001     3662         AAP1
20002     3662         AAP1
20003     3663         APP1
202118    3663         AAP1
110001    3662         AAP3

我遇到的问题是遍历层次结构类型,userid,f_element和o_element。我可以遍历层次结构,但我对如何在没有组合元素的情况下有一个心理障碍。注意:对于APP3的FFA用户只获得一个f_element和o_element,因为他没有140和2003作为该行的一部分。

sql oracle
1个回答
1
投票

@Miguel,这是一个使用CONNECT BY查询的解决方案

数据

  CREATE TABLE FSECURE
   (    "USERID" VARCHAR2(100 BYTE), 
    "F_ELEMENT" VARCHAR2(6 BYTE), 
    "O_ELEMENT" VARCHAR2(20 BYTE), 
    "TYPE" VARCHAR2(20 BYTE)
   ); 
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','140','2003','APP1');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','280','2003','APP1');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('GGA','202118','2003','APP2');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('GGA','140','2004','APP2');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('RFA','202116','3662','APP3');
Insert into FSECURE (USERID,F_ELEMENT,O_ELEMENT,TYPE) values ('FFA','110001','3662','APP3');

CREATE TABLE FVOL
       (    "ORG" VARCHAR2(6 BYTE), 
        "ORG_PRED" VARCHAR2(6 BYTE)
       );
Insert into FVOL (ORG,ORG_PRED) values ('2003',null);
Insert into FVOL (ORG,ORG_PRED) values ('3661','2003');
Insert into FVOL (ORG,ORG_PRED) values ('3662','2003');
Insert into FVOL (ORG,ORG_PRED) values ('2009',null);
Insert into FVOL (ORG,ORG_PRED) values ('366X','2009');
Insert into FVOL (ORG,ORG_PRED) values ('366P','2009');
Insert into FVOL (ORG,ORG_PRED) values ('2004',null);
Insert into FVOL (ORG,ORG_PRED) values ('1114','2004');
Insert into FVOL (ORG,ORG_PRED) values ('2224','2004');



CREATE TABLE "FVAL" 
   (    "FUND" VARCHAR2(6 BYTE), 
    "FUND_PRED" VARCHAR2(6 BYTE)
   );
Insert into FVAL (FUND,FUND_PRED) values ('140',null);
Insert into FVAL (FUND,FUND_PRED) values ('280',null);
Insert into FVAL (FUND,FUND_PRED) values ('2000','140');
Insert into FVAL (FUND,FUND_PRED) values ('20001','2000');
Insert into FVAL (FUND,FUND_PRED) values ('20002','2000');
Insert into FVAL (FUND,FUND_PRED) values ('20003','2000');
Insert into FVAL (FUND,FUND_PRED) values ('202118','2000');
Insert into FVAL (FUND,FUND_PRED) values ('2800','280');
Insert into FVAL (FUND,FUND_PRED) values ('280001','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280002','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280003','2800');
Insert into FVAL (FUND,FUND_PRED) values ('280004','2800');
Insert into FVAL (FUND,FUND_PRED) values ('110001','11000');
Insert into FVAL (FUND,FUND_PRED) values ('110002','11000');

WITH v_fval
AS
(SELECT fund, r_fund
   FROM (SELECT fund, 
               connect_by_root fund AS r_fund,
               connect_by_isleaf AS l_fund
          FROM fval 
         START WITH fund_pred IS NULL
         CONNECT BY PRIOR fund = fund_pred)
  WHERE l_fund = 1)
, v_fvol 
AS
(SELECT org, r_org
   FROM (SELECT org, 
               connect_by_root org AS r_org,
               connect_by_isleaf AS l_org
          FROM fvol 
          START WITH org_pred IS NULL
          CONNECT BY PRIOR org = org_pred)
  WHERE l_org = 1)
SELECT fsecure.userid, 
       NVL(v_fvol.org, fsecure.o_element) AS org,
       NVL(v_fval.fund, fsecure.f_element) AS fund, 
       fsecure.type
  FROM fsecure LEFT JOIN v_fvol 
                 ON (fsecure.o_element = v_fvol.r_org)
               LEFT JOIN v_fval 
                 ON (fsecure.f_element = v_fval.r_fund)
 WHERE fsecure.userid = 'FFA'
 ORDER BY fsecure.userid, v_fvol.org, v_fval.fund  ;

输出如下

USERID  ORG FUND    TYPE
FFA 3661    20001   APP1
FFA 3661    20002   APP1
FFA 3661    20003   APP1
FFA 3661    202118  APP1
FFA 3661    280001  APP1
FFA 3661    280002  APP1
FFA 3661    280003  APP1
FFA 3661    280004  APP1
FFA 3662    20001   APP1
FFA 3662    20002   APP1
FFA 3662    20003   APP1
FFA 3662    202118  APP1
FFA 3662    280001  APP1
FFA 3662    280002  APP1
FFA 3662    280003  APP1
FFA 3662    280004  APP1
FFA 3662    110001  APP3

说明。

2个视图获取层次结构的叶节点,主查询将它们连接起来。我建议单独运行视图以更好地理解。

这里的SQL小提琴演示 - http://sqlfiddle.com/#!4/a2a751/23

© www.soinside.com 2019 - 2024. All rights reserved.