Oracle:在父子方案中需要帮助

时间:2017-03-30 15:14:33

标签: sql oracle

需要有关以下方案的帮助。

表格结构:

ACCT_XREF

CREATE TABLE ACCT_XREF
(
 ACCT_NO VARCHAR2(10),
 PRNT_ACCT_NO VARCHAR2(10),
 PRTY_ROWID VARCHAR2(10),
 ACCT_ROWID VARCHAR2(10)
);

INPUT_ACCTROWID

CREATE TABLE INPUT_ACCTROWID
(
 ACCT_ROWID VARCHAR2(10)
);

样本数据:

INSERT INTO ACCT_XREF VALUES('1000',NULL,'100','1');
INSERT INTO ACCT_XREF VALUES('1001','1003','NULL','2');
INSERT INTO ACCT_XREF VALUES('1003',NULL,'102','3');

INSERT INTO INPUT_ACCTROWID VALUES('1');
INSERT INTO INPUT_ACCTROWID VALUES('2');

ACCT_XREF

i / p数据:

ACCT_NO    PRNT_ACCT_NO    PRTY_ROWID      ACCT_ROWID
-----------------------------------------------------
1000       NULL            100             1
1001       1003            NULL            2
1003       NULL            102             3

INPUT_ACCTROWID

 ACCT_ROWID
 ----------
 1
 2

预期输出

ACCT_NO   PRTY_ROWID
--------------------
1000      100
1001      102

这里的问题是:

  • ACCT_XREF是基于层次结构的,
  • 因此,当PRNT_ACCT_NO为非NULL时,PRTY_ROWID将为NULL,
  • 在这种情况下,选择PRNT_ACCT_NO并查询同一个表 ACCT_NO作为匹配条件并获取与之链接的Party 帐户即PRTY_ROWID

我已经努力实现同样的目标,以下是我的查询:

SELECT ALL_INP.ACCT_NO,COALESCE(ALL_INP.PRTY_ROWID,C.PRTY_ROWID)
FROM
(
 SELECT A.*
 FROM
 ACCT_XREF A
 JOIN
 INPUT_ACCTROWID B 
 ON A.ACCT_ROWID=B.ACCT_ROWID
)ALL_INP
LEFT OUTER JOIN
ACCT_XREF C
ON ALL_INP.PRNT_ACCT_NO=C.ACCT_NO;

不确定这是最好的方法,所以想知道是否有更好的选择。谢谢提前。

2 个答案:

答案 0 :(得分:0)

要解决此问题,请在select中创建一个子查询,如下一个查询:

2

答案 1 :(得分:0)

我明白你的意思了。你有递归表,主要有两种类型的数据组件。它们是PARENT类型(PRNT_ACCT_NO为NULL)或CHILD类型(PRNT_ACCT_NO为NOT NULL)。如果请求CHILD,那么在将数据作为输出

之前,它应首先导航到父级

以下是如何解决这样的问题

  1. 找出父节点并仅获取CHILD节点所需的数据
  2. 找出父节点并仅获取CHILD节点所需的数据
  3. 获取SOLO节点(已经是父母 - 没有孩子)的节点数据
  4. 合并这两个数据集
  5. 将其与最终驱动表INPUT_ACCTROWID混为一起,仅用于获取所需的选择性数据。

     SELECT XREF.ACCT_NO, XREF.PRTY_ROWID
        FROM    (SELECT CHILD.ACCT_NO AS ACCT_NO,
                        FATHER.PRTY_ROWID AS PRTY_ROWID,
                        CHILD.ACCT_ROWID AS ACCT_ROWID
                   FROM    ACCT_XREF FATHER
                        JOIN
                           ACCT_XREF CHILD
                        ON FATHER.ACCT_NO = CHILD.PRNT_ACCT_NO
                  WHERE CHILD.PRNT_ACCT_NO IS NOT NULL --**CHILD NODES ONLY**
                 UNION ALL
                 SELECT SOLO.ACCT_NO AS ACCT_NO,
                        SOLO.PRTY_ROWID AS PRTY_ROWID,
                        SOLO.ACCT_ROWID AS ACCT_ROWID
                   FROM ACCT_XREF SOLO
                  WHERE SOLO.PRNT_ACCT_NO IS NULL --**PARENT/SOLO NODES ONLY**
                ) XREF
             JOIN
                INPUT_ACCTROWID INPUT1 --**DRIVING TABLE JOIN**
             ON XREF.ACCT_ROWID = INPUT1.ACCT_ROWID
    ORDER BY 1 ASC    
    
  6. 这是输出

        ACCT_NO    PRTY_ROWID
        1000       100
        1001       102
    

    这是一个更容易理解执行计划的解释计划:

    SELECT STATEMENT  ALL_ROWSCost: 74  Bytes: 84  Cardinality: 3                          
        9 SORT ORDER BY  Cost: 74  Bytes: 84  Cardinality: 3                      
            8 HASH JOIN  Cost: 73  Bytes: 84  Cardinality: 3                  
                1 TABLE ACCESS FULL TABLE CONTACTDBA.INPUT_ACCTROWID Cost: 18  Bytes: 14  Cardinality: 2              
                7 VIEW CONTACTDBA. Cost: 55  Bytes: 63  Cardinality: 3              
                    6 UNION-ALL          
                        4 HASH JOIN  Cost: 37  Bytes: 35  Cardinality: 1      
                            2 TABLE ACCESS FULL TABLE CONTACTDBA.ACCT_XREF Cost: 18  Bytes: 21  Cardinality: 1  
                            3 TABLE ACCESS FULL TABLE CONTACTDBA.ACCT_XREF Cost: 18  Bytes: 42  Cardinality: 3  
                        5 TABLE ACCESS FULL TABLE CONTACTDBA.ACCT_XREF Cost: 18  Bytes: 56  Cardinality: 2      
    

    我希望这会有所帮助。