2

我有 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 作为数据库。

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

4

2 回答 2

2

谢谢你的有趣问题

1步。为规范的 oracle 层次结构准备表。

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
于 2012-04-26T10:39:35.850 回答
1

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

多表原理与单表相同:

一世。您确定“起始行”。
ii. 您可以根据“当前”集定义识别下一级行的逻辑。

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

这些查询总是很棘手,并且与许多 SQL 问题一样,它通常有助于从简单开始并增加复杂性。

于 2012-04-26T08:02:17.680 回答