如何在Oracle中生成分层查询?

时间:2016-08-02 12:52:45

标签: sql oracle hierarchical-data recursive-query

我有一张桌子,但是我无法写出提取树的关系。

以下是数据示例:

LOT_ID | LOT_PRODUCED | ITEM_PRODUCED | ITEM_USED | LOT_USED | OPERATION | STEP  
------ | ------------ | ------------- | --------- | -------- | --------- | ---- 
1      | LOT_1        | ITEM_1        | null      | null     | P         | STEP_1
1      | null         | null          | ITEM_1    | LOT_1    | C         | STEP_2
5      | null         | null          | ITEM_2    | LOT_2    | C         | STEP_2
5      | LOT_2        | ITEM_2        | null      | null     | P         | STEP_8
5      | null         | null          | ITEM_2    | LOT_2    | C         | STEP_1
6      | null         | null          | ITEM_2    | LOT_7    | C         | STEP_8

从LOT_PRODUCED = LOT_1开始,我想要一棵树,其中每一步都与起始地段的步骤相关联。

因此,在此示例中,我们看到STEP_1(生成LOT_1的步骤)消耗LOT_2。那批是由STEP_8制作的。此步骤反过来消耗LOT_7。等等。

我认为我理解START WITH和CONNECT BY的概念,但由于链接在列之间“跳跃”,我无法解决这种情况。没有明确的父母和孩子。

如果使用简单查询无法解决这个问题,我会对存储过程开放。

编辑:

Here is a drawing of the data shown above

所以在左边有链接的解释:

  • 一步耗尽
  • 步骤产生很多

在右侧有链接:连接器上的数字是上面显示的数据的行号。

1 个答案:

答案 0 :(得分:0)

我想出了一个问题:

SELECT DISTINCT G.STEP,
  LOT_USED,
  ITEM_USED,
  LOT_PRODUCED,
  ITEM_PRODUCED
FROM GENEALOGY G
  START WITH G.STEP      = 'STEP01'
  CONNECT BY LOTPRODUCED = PRIOR LOTUSED
AND ITEMPRODUCED         = PRIOR ITEMUSED
ORDER BY G.STEP

但这只会返回第一级消费: 从开始步骤开始,我得到了很多,然后对于这些批次中的每一个,我都得到了产生它的步骤。如果有的话,我也可以通过开始步骤获得批次。

要链接我的示例数据,我得到(从STEP_1开始):

STEP   | LOT_USED | ITEM_USED | LOT_PRODUCED | ITEM_PRODUCED
-------|----------|-----------|--------------|---------------
STEP_1 | LOT_2    | ITEM_2    |              |
STEP_1 |          |           | LOT_1        | ITEM_1
STEP_8 |          |           | LOT_2        | ITEM_2

然后我更改了查询以将现有部分包含为子查询:

SELECT DISTINCT H.STEP,
  LOTUSED,
  ITEMUSED,
  LOTPRODUCED,
  ITEMPRODUCED
FROM GENEALOGY H
  START WITH H.STEP IN
    (SELECT DISTINCT G.STEP
     FROM GENEALOGY G
       START WITH G.STEP = 'STEP_1'
       CONNECT BY LOTPRODUCED = PRIOR LOTUSED
     AND ITEMPRODUCED         = PRIOR ITEMUSED
    )
  CONNECT BY LOTPRODUCED = PRIOR LOTUSED
AND ITEMPRODUCED         = PRIOR ITEMUSED
ORDER BY H.STEP
然后我得到2级消费。

要链接我的示例数据,我得到(从STEP_1开始):

STEP   | LOT_USED | ITEM_USED | LOT_PRODUCED | ITEM_PRODUCED
-------|----------|-----------|--------------|---------------
STEP_1 | LOT_2    | ITEM_2    |              |
STEP_1 |          |           | LOT_1        | ITEM_1
STEP_8 |          |           | LOT_2        | ITEM_2
STEP_8 | LOT_7    | ITEM_2    |              |

因此,我可以获得与查询中存在的CONNECT BY一样多的消耗级别。 但我当然希望获得完整的树。 我事先并不知道等级的数量,即使我知道它是例如30,我的查询也会毫无理由地“巨大”。

有人有想法帮助我为我的问题构建更简单的查询吗? 也许可以使用P(产品)和C(消耗)OPERATION字段和LOT_ID?