复杂的SQL查询,在单个查询中列出树

时间:2014-08-27 07:41:40

标签: sql oracle

我有一个Oracle SQL(10g)表,其中包含与物料清单相关的数据。例如,一个项目有一个原材料清单,该清单可能包含一个带有自己的物料清单的物品,在该清单中可能有一个物品可能有自己的物料清单。

我需要列出物料清单,其相关物品以及是否有任何子物品,然后是物品清单,如果这些物品有任何清单,那么该清单等等等等..... 我们不知道项目的树级别,它是随机的。

我现在无法发布图片,我将解释如下:

项目A ------原料1
项目A ------原料2
项目A ------半成品1 - 原料3
项目A ------半成品1 - 原料4
项目A ------半成品1 - 半成品2 - 原料5
项目A ------半成品1 - 半成品2 - 半成品3 - 原料6
等,等....

新例子:

ITEMCODE BOMCODE数量
ABCD XYZ 1
ABCD2 XYZ 8
ABCD3 XYZ 3
ABCD4 XYZ 56
ABCD76 ABCD3 1
ABCD98 ABCD3 5
ABCD34 ABCD4 2
ABCD21 ABCD4 8
ABCD90 ABCD98 9
ABCD31 ABCD98 2

表中有3个字段,itemcode,bomcode,qty。

这个例子适用于' xyz'项目,生产' xyz'项目我们需要物品代码中列出的项目与提到的数量,如果你看,有一些项目,如' abcd3',' abcd4',它们有自己的物料清单,相同的' abcd98&#39 ;.我不知道水平,因为它是随机的,它可以有任意数量的水平。

2 个答案:

答案 0 :(得分:0)

结果:

| LEVEL | BOMCODE | ITEMCODE | QTY |
|-------|---------|----------|-----|
|     1 |     XYZ |     ABCD |   1 |
|     1 |     XYZ |    ABCD2 |   8 |
|     1 |     XYZ |    ABCD3 |   3 |
|     1 |     XYZ |    ABCD4 |  56 |
|     2 |   ABCD3 |   ABCD76 |   1 |
|     2 |   ABCD3 |   ABCD98 |   5 |
|     2 |   ABCD4 |   ABCD21 |   8 |
|     2 |   ABCD4 |   ABCD34 |   2 |
|     3 |  ABCD98 |   ABCD31 |   2 |
|     3 |  ABCD98 |   ABCD90 |   9 |

由此查询生成:

SELECT
  LEVEL, BOMCODE, ITEMCODE, QTY
FROM
  BOMS
WHERE
  LEVEL <= 30
  START WITH BOMCODE      = 'XYZ'
  CONNECT BY PRIOR ITEMCODE = BOMCODE
ORDER BY
  LEVEL, BOMCODE, ITEMCODE, QTY
;

我使用的是BOMS的表名,而且where子句中使用的级别数是任意的,它实际上是递归次数的“安全”。

请参阅This SQLfiddle demo

不确定这是否是你想要的。也许如下:

PATH
------------------------------
XYZ/ABCD
XYZ/ABCD2
XYZ/ABCD3
XYZ/ABCD4
XYZ/ABCD3/ABCD76
XYZ/ABCD3/ABCD98
XYZ/ABCD4/ABCD21
XYZ/ABCD4/ABCD34
XYZ/ABCD3/ABCD98/ABCD31
XYZ/ABCD3/ABCD98/ABCD90

由:

SELECT
   LPAD(' ', 2*level-1)||'XYZ'||SYS_CONNECT_BY_PATH(ITEMCODE, '/') "Path"
FROM
  BOMS
WHERE
  LEVEL <= 30
  START WITH BOMCODE      = 'XYZ'
  CONNECT BY PRIOR ITEMCODE = BOMCODE
ORDER BY
  LEVEL, BOMCODE, ITEMCODE, QTY
;

答案 1 :(得分:0)

正如@Used_By_Already所解释的,以下查询是我的问题的答案:

SELECT
  LEVEL, BOMCODE, ITEMCODE, QTY
FROM
  BOMS
WHERE
  LEVEL <= 30
  START WITH BOMCODE      = 'XYZ'
  CONNECT BY PRIOR ITEMCODE = BOMCODE
ORDER BY
  LEVEL, BOMCODE, ITEMCODE, QTY
;