在oracle中获取分层数据的父路径

时间:2017-11-09 20:22:15

标签: sql oracle hierarchical-data

我有三个表,CATEGORY,GROUPING和PERFORMER,其中类别的直接子项可以是任何其他类别或分组或执行者,分组的子项可以是任何其他分组或执行者,在给定此类上下文时,类别ID或分组ID或提供了执行者ID然后我需要获得给定id的整个父路径。如何在oracle中使用SQL

enter image description here

if performer_id= 300 then result should be 300->202->201->101->100
if grouping_id = 203 then result should be 203->102->101->100
if category_id = 103 then result should be 103->101->100

1 个答案:

答案 0 :(得分:0)

堆栈溢出不是编码站点,您应该始终包含您尝试过的示例。也就是说,我觉得这很有趣,我想我会试一试。

这是一种完全暴力的方法。我从每个级别提取层次结构,然后使用listagg将它们组合在一起:

WITH
    category
    AS
        (SELECT '100' category_id, NULL parent_id
           FROM DUAL
         UNION ALL
         SELECT '101' category_id, '100' parent_id
           FROM DUAL
         UNION ALL
         SELECT '102' category_id, '101' parent_id
           FROM DUAL
         UNION ALL
         SELECT '103' category_id, '101' parent_id
           FROM DUAL),
    GROUPING
    AS
        (SELECT '200' GROUPING_ID, NULL parent_id, '101' category_id
           FROM DUAL
         UNION ALL
         SELECT '201' GROUPING_ID, '200' parent_id, '101' category_id
           FROM DUAL
         UNION ALL
         SELECT '202' GROUPING_ID, '201' parent_id, '101' category_id
           FROM DUAL
         UNION ALL
         SELECT '203' GROUPING_ID, NULL parent_id, '102' category_id
           FROM DUAL),
    performer
    AS
        (SELECT '300' performer_id, '202' GROUPING_ID, '101' category_id
           FROM DUAL
         UNION ALL
         SELECT '301' performer_id, '201' GROUPING_ID, '101' category_id
           FROM DUAL
         UNION ALL
         SELECT '302' performer_id, '203' GROUPING_ID, '103' category_id
           FROM DUAL
         UNION ALL
         SELECT '303' performer_id, NULL GROUPING_ID, '102' category_id
           FROM DUAL),
    pset (p_gid, p_parentid, p_catid)
    AS
        (SELECT GROUPING.GROUPING_ID, parent_id, GROUPING.category_id
           FROM performer INNER JOIN GROUPING ON performer.GROUPING_ID = GROUPING.GROUPING_ID
          WHERE performer_id = '300'
         UNION ALL
         SELECT GROUPING_ID, parent_id, category_id
           FROM pset INNER JOIN GROUPING ON GROUPING_ID = p_parentid),
    cset (p_catid, p_parent)
    AS
        (SELECT p_catid, parent_id
           FROM pset INNER JOIN category ON pset.p_catid = category.category_id

         UNION ALL
         SELECT category_id, parent_id
           FROM cset INNER JOIN category ON category_id = p_parent),
    dset
    AS
        (SELECT p_catid
           FROM cset
         UNION
         SELECT p_gid
           FROM pset
         UNION
         SELECT '300'
           FROM DUAL)
SELECT LISTAGG (p_catid, '->') WITHIN GROUP (ORDER BY p_catid DESC) AS performer_chain
  FROM dset

答案是

PERFORMER_CHAIN
300->202->201->200->101->100