Oracle 11中的递归SQL选择查询

时间:2012-04-26 07:47:04

标签: sql oracle hierarchical-data

我有4个不同的表格,bommodulebomitemmapbomitemmodulemapbomparentsubmodule

bommodule表

CREATE TABLE "BOMMODULE"
(
  "MODULEID"         NUMBER(10,0) NOT NULL ENABLE,
  "ISROOTMODULE"     NUMBER(1,0) NOT NULL ENABLE,
  "MODULENAME"       VARCHAR2(255 CHAR),
  .....
)

bomitem表

CREATE TABLE "BOMITEM"
  (
    "ITEMID"     NUMBER(10,0) NOT NULL ENABLE,
    ....
  )

mapbomitemmodule-table:(此表将项目映射到一个或多个模块)。

CREATE TABLE "SSIS2"."MAPBOMITEMMODULE"
  (
    "ITEMID"   NUMBER(10,0) NOT NULL ENABLE,
    "MODULEID" NUMBER(10,0) NOT NULL ENABLE,
    CONSTRAINT "MAP_ITEM_MODULE_FK" FOREIGN KEY ("ITEMID") REFERENCES "BOMITEM" ("ITEMID") ENABLE,
    CONSTRAINT "MAP_MODULE_ITEM_FK" FOREIGN KEY ("MODULEID") REFERENCES "BOMMODULE" ("MODULEID") ENABLE
  )

mapbomparentsubmodule-table:(此表将模块映射到子模块)

CREATE TABLE "MAPBOMPARENTSUBMODULE"
  (
    "PARENTMODULEID" NUMBER(10,0) NOT NULL ENABLE,
    "SUBMODULEID"    NUMBER(10,0) NOT NULL ENABLE,
    CONSTRAINT "PARENTMODULE_SUBMODULE_FK" FOREIGN KEY ("SUBMODULEID") REFERENCES "BOMMODULE" ("MODULEID") ENABLE,
    CONSTRAINT "SUBMODULE_PARENTMODULE_FK" FOREIGN KEY ("PARENTMODULEID") REFERENCES "BOMMODULE" ("MODULEID") ENABLE
  )

想象一下像这样的结构。

root module
  submodule 1
    submodule 2
      submodule 3
        submodule 4
          submodule 5
          item 5
          item 6
          item 7
      item 2
      item 3
      item 4
  item 1

我需要找出属于特定moduleId的所有项目。应列出所有子模块级别的所有项目。

我该怎么做?我使用Oracle 11作为数据库。

非常感谢你的帮助,非常感谢!

2 个答案:

答案 0 :(得分:2)

感谢有趣的问题

1步。为规范的oracle hierarhy准备表格。

select PARENTMODULEID, SUBMODULEID, 1 HTYPE
from MAPBOMPARENTSUBMODULE

union all

select null, MODULEID, 1 --link root to null parent
from BOMMODULE B
where ISROOTMODULE = 1

union all 

select MODULEID, ITEMID, 2
from MAPBOMITEMMODULE

2步。使用connect by

展开层次结构
select PARENTMODULEID
      ,SUBMODULEID
      ,HTYPE
      ,level
      ,lpad('|', level*3, '|')
from
(
    select PARENTMODULEID, SUBMODULEID, 1 HTYPE
    from MAPBOMPARENTSUBMODULE

    union all

    select null, MODULEID, 1
    from BOMMODULE B
    where ISROOTMODULE = 1

    union all 

    select MODULEID, ITEMID, 2
    from MAPBOMITEMMODULE
) ALL_HIER
connect by prior SUBMODULEID = PARENTMODULEID
       and prior HTYPE = 1 --parent is always module
start with ALL_HIER.PARENTMODULEID is null
order siblings by HTYPE

3步。最后。加入价值表。

select PARENTMODULEID
      ,SUBMODULEID
      ,HTYPE
      ,ALL_VAL.VAL
      ,level
      ,rpad('|', level * 3, ' ') || ALL_VAL.VAL
from
(
    select PARENTMODULEID, SUBMODULEID, 1 HTYPE
    from MAPBOMPARENTSUBMODULE

    union all

    select null, MODULEID, 1
    from BOMMODULE B
    where ISROOTMODULE = 1

    union all 

    select MODULEID, ITEMID, 2
    from MAPBOMITEMMODULE
) ALL_HIER
,(
    select MODULEID VAL_ID, MODULENAME VAL, 1 VTYPE
    from BOMMODULE

    union all

    select ITEMID, 'item '||ITEMID, 2
    from BOMITEM
) ALL_VAL
where ALL_VAL.VAL_ID = ALL_HIER.SUBMODULEID
  and ALL_VAL.VTYPE = ALL_HIER.HTYPE
connect by prior SUBMODULEID = PARENTMODULEID
       and prior HTYPE = 1
start with ALL_HIER.PARENTMODULEID is null
order siblings by HTYPE

答案 1 :(得分:1)

首先使用CONNECT BY子句调查hierarchical query的使用。它专为这种类型的模型而设计。

多个表的原理与单个表的原理相同:

我。你确定“起始行”。
II。您可以根据“当前”集定义用于标识下一级行的逻辑。

在某些情况下,它可以帮助在内联视图中定义分层查询,特别是如果单个表包含识别起始行和级别之间的连接所需的所有数据。

这些查询总是很棘手,而且与许多SQL问题一样,启动简单并增加复杂性通常会有所帮助。