如何在Oracle SQL LEVEL查询中将原始“开头为” ID捕获为列

时间:2019-03-01 18:45:08

标签: sql oracle

使用一个庞大的材料数据库作为“输入”消耗掉,以创建多个世代的各种“输出”。最终输出(用于市场的产品)在其历史上可能具有十几代的输入。这些输入中的每一个都有自己的记录。

当前,我正在使用LEVEL创建此家谱的自顶向下视图(意味着从最终产品开始,然后再回溯所有输入)。

代码的简化/概念示例如下:

SELECT
 OL.LOT_NAME AS output_id,
 IL.LOT_NAME AS input_id,
 LEVEL
FROM GENEALOGY_TABLE G
INNER JOIN LOT_TABLE OL
 on G.OUTPUT_LOT_KEY = OL.LOT_KEY
INNER JOIN LOT_TABLE IL
 on G.INPUT_LOT_KEY = IL.LOT_KEY
START WITH OL.LOT_NAME IN ('X', 'Y', etc...)
CONNECT BY NOCYCLE PRIOR IL.LOT_NAME = OL.LOT_NAME
ORDER BY LEVEL

我想在此输出表中添加另一列,以保留原始“ START WITH”值,该值是任何给定记录的来源。这意味着即使记录的级别为10,我也不会仅看到该材料创建的级别9的输出,而是上面的多个最终产品(“ X”,“ Y”等)中的哪一个?例如),最终是在下游创建的。

Oracle是否具有可以处理此问题的功能?我有没有简单的技巧可以做到这一点?任何建议都会很棒。

2 个答案:

答案 0 :(得分:2)

您可以使用the connect_by_root operator

SELECT
 OL.LOT_NAME AS output_id,
 IL.LOT_NAME AS input_id,
 LEVEL,
 CONNECT_BY_ROOT(OL.LOT_NAME) AS STARTED_WITH
FROM GENEALOGY_TABLE G
...

使用HR模式表的快速演示:

SELECT employee_id, last_name, manager_id, connect_by_root(manager_id)
FROM employees
START WITH manager_id in (101, 102)
CONNECT BY PRIOR employee_id = manager_id;

EMPLOYEE_ID LAST_NAME                 MANAGER_ID CONNECT_BY_ROOT(MANAGER_ID)
----------- ------------------------- ---------- ---------------------------
        108 Greenberg                        101                         101
        109 Faviet                           108                         101
        110 Chen                             108                         101
        111 Sciarra                          108                         101
        112 Urman                            108                         101
        113 Popp                             108                         101
        200 Whalen                           101                         101
        203 Mavris                           101                         101
        204 Baer                             101                         101
        205 Higgins                          101                         101
        206 Gietz                            205                         101
        103 Hunold                           102                         102
        104 Ernst                            103                         102
        105 Austin                           103                         102
        106 Pataballa                        103                         102
        107 Lorentz                          103                         102

16 rows selected. 

答案 1 :(得分:1)

有了Oracle,总有办法。使用CONNECT_BY_ROOT