代码之家  ›  专栏  ›  技术社区  ›  LiborStefek

Oracle-如何在分层查询中使用join避免笛卡尔积

  •  3
  • LiborStefek  · 技术社区  · 7 年前

    我需要从两个表中选择数据—首先保存层次结构数据( STR REQ 表),我需要选择层次结构并将其与 要求 桌子。

    CREATE TABLE REQ (prop int,          ord  varchar2(10));
    CREATE TABLE STR (par  varchar2(10), chld varchar2(10));
    
    INSERT INTO REQ VALUES (100,'A');
    INSERT INTO REQ VALUES (101,'A');
    INSERT INTO REQ VALUES (102,'B');
    INSERT INTO STR VALUES ('A','A1');
    INSERT INTO STR VALUES ('A','A2');
    INSERT INTO STR VALUES ('A1','A3');
    INSERT INTO STR VALUES ('A2','A5');
    INSERT INTO STR VALUES ('A3','A6');
    INSERT INTO STR VALUES ('B','B1');
    INSERT INTO STR VALUES ('B','B2');
    

    基本查询来源 STR公司 例如,表给出了以下层次结构:

    SELECT par, chld, level
    FROM STR
    CONNECT BY PRIOR chld = par
    START WITH PAR IN (SELECT ord FROM REQ WHERE prop = 100);
    

    等级可以:

    PAR        CHLD            LEVEL
    ---------- ---------- ----------
    A          A1                  1
    A1         A3                  2
    A3         A6                  3
    A          A2                  1
    A2         A5                  2
    

    我需要添加到列的结果值中 prop 要求 我希望得到这样的结果:

    PAR        CHLD            LEVEL  PROP 
    ---------- ---------- ---------- ----- 
    A          A1                  1   100   
    A1         A3                  2   100
    A3         A6                  3   100
    A          A2                  1   100
    A2         A5                  2   100
    

    SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
    FROM STR
    ,    REQ
    WHERE REQ.prop = 100
    CONNECT BY PRIOR STR.chld = STR.par
    START WITH STR.PAR = REQ.ord;
    

    PAR        CHLD            LEVEL       PROP ORD      
    ---------- ---------- ---------- ---------- ----------
    A          A1                  1        100 A         
    A1         A3                  2        100 A         
    A3         A6                  3        100 A         
    A3         A6                  3        100 A        ! extra
    A3         A6                  3        100 A        ! rows !
    A1         A3                  2        100 A        !
    A3         A6                  3        100 A        ! 
    A3         A6                  3        100 A        ! 
    A3         A6                  3        100 A        ! 
    A          A2                  1        100 A         
    A2         A5                  2        100 A         
    A2         A5                  2        100 A        ! 
    12 rows selected 
    

    我有什么方法可以更正查询以获得预期的数据?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Radagast81    7 年前

    下面的查询应该可以做到这一点-不知道它是否理想,但它可以工作:

    SELECT DISTINCT STR.par, STR.chld, level
         , connect_by_root req.prop AS prop
         , connect_by_root req.ord AS ord
      FROM str
      LEFT JOIN REQ
        ON REQ.ord = str.par
    CONNECT BY PRIOR STR.chld = STR.par
      START WITH REQ.prop = 100
    
        2
  •  0
  •   LiborStefek    7 年前

    我找到了另一种方法-不知道是否理想,但似乎有效:

    SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
    FROM STR
    ,    REQ
    CONNECT BY PRIOR STR.chld = STR.par
    AND        PRIOR REQ.prop = REQ.prop
    START WITH STR.PAR = REQ.ord AND REQ.prop = 100;