如何在Oracle SQL中检索子行的所有递归父级?

时间:2018-12-18 08:33:59

标签: oracle oracle11g

我有一个类别产品的分层数据。这是3级层次结构,所有产品将始终分配到最后一级。我想显示按类别-子类别和子子类别分组的所有产品的明细报表。只有那些类别会显示在我们具有产品结果的报告上。 (结果产品由其他标准决定,超出了此问题的范围。)

如何获取所有类别数据,直到在oracle的根目录级别。

样本数据

 CategoryId   Name           Parent
    1            Clothing       NULL
    2            Men's Wear     1
    3            Shirt          2
    4            T-Shirt        2
    5            Women's Wear   1
    6            Salwar         5
    7            Saree          5
    8            Electronics    NULL
    9            Computers      8
    10           Mobiles        8

产品表将具有类别ID参考。例如3、4或6、7等 我只想检索直到我们拥有产品的根级别的类别。我在下面查询,但是我不确定这是否是为START WITH子句指定多个值的好习惯。有更好的选择吗?

SELECT DISTINCT CategoryId,Name,Parent
FROM   tblCategory
START WITH CategoryId IN (3,6)
CONNECT BY CategoryId = PRIOR Parent

对于上面的查询,我只指定了两个类别,但在现实世界中可能是数千个。以下是仅显示选定产品类别的结果数据。

输出:

 CategoryId  Name          Parent
    1        Clothing      NULL
    2        Men's Wear    1
    3        Shirt         2
    5        Women's Wear  1
    6        Salwar        5  

1 个答案:

答案 0 :(得分:1)

所以您基本上解决了您的问题。您可以像以前一样列出ID,也可以将其存储在某个地方并在IN子查询中使用,例如:

with tblCategory(CategoryId, Name, Parent) as (
    select  1, 'Clothing',      null from dual union all
    select  2, 'Men''s Wear',   1    from dual union all
    select  3, 'Shirt',         2    from dual union all
    select  4, 'T-Shirt',       3    from dual union all
    select  5, 'Women''s Wear', 1    from dual union all
    select  6, 'Salwar',        5    from dual union all
    select  7, 'Saree',         5    from dual union all
    select  8, 'Electronics',   null from dual union all
    select  9, 'Computers',     8    from dual union all
    select 10, 'Mobiles',       8    from dual ),
  ids(cid) as (select 3 from dual union all select 6 from dual)
select distinct categoryid, name, parent
  from tblcategory
  start with categoryid in (select cid from ids)
  connect by categoryid = prior parent

结果:

CATEGORYID NAME             PARENT
---------- ------------ ----------
         6 Salwar                5
         3 Shirt                 2
         5 Women's Wear          1
         2 Men's Wear            1
         1 Clothing   

您还可以像下面这样产生更具可读性的输出:

select connect_by_root(categoryid) root, 
       sys_connect_by_path(name, ' => ') path
  from tblcategory
  where connect_by_isleaf = 1
  start with categoryid in (select cid from ids)
  connect by categoryid = prior parent

结果:

  ROOT PATH
------ --------------------------------------------------------------------------------
     3  => Shirt => Men's Wear => Clothing
     6  => Salwar => Women's Wear => Clothing