生成分层路径

Generate hierarchical path

我有一个 classstructure table:

create table classstructure (classstructureid number(8,0), classificationid varchar2(25), parent number(8,0));

insert into classstructure(classstructureid, classificationid, parent) values(1001, 'FLEET', null);
insert into classstructure(classstructureid, classificationid, parent) values(1002, 'LIGHTDUTYVEHICLE', 1001);
insert into classstructure(classstructureid, classificationid, parent) values(1004, 'MEDIUMDUTYVEHICLE', 1001);
insert into classstructure(classstructureid, classificationid, parent) values(1022, 'ACTIVETRANSPORTATION', null);
insert into classstructure(classstructureid, classificationid, parent) values(1023, 'FACILITYWALKWAY', 1022);
insert into classstructure(classstructureid, classificationid, parent) values(1024, 'TRAIL', 1022);
insert into classstructure(classstructureid, classificationid, parent) values(1085, 'SIDEWALK', 1022);
insert into classstructure(classstructureid, classificationid, parent) values(1091, 'SDWRAMP', 1085);
commit;

select * from classstructure;

CLASSSTRUCTUREID CLASSIFICATIONID              PARENT
---------------- ------------------------- ----------
            1001 FLEET                               
            1002 LIGHTDUTYVEHICLE                1001
            1004 MEDIUMDUTYVEHICLE               1001

            1022 ACTIVETRANSPORTATION                
            1023 FACILITYWALKWAY                 1022
            1024 TRAIL                           1022
            1085 SIDEWALK                        1022
            1091 SDWRAMP                         1085

我想将记录折叠到层次结构路径:

HIERARCHYPATH
---------------------------
FLEET \ LIGHTDUTYVEHICLE
FLEET \ MEDIUMDUTYVEHICLE 

ACTIVETRANSPORTATION \ FACILITYWALKWAY
ACTIVETRANSPORTATION \ TRAIL
ACTIVETRANSPORTATION \ SIDEWALK
ACTIVETRANSPORTATION \ SIDEWALK \ SDWRAMP

我该怎么做?

您可以使用sys_connect_by_path()(因为Oracle 10g Release 2)功能:

select ltrim(sys_connect_by_path(classificationid, ' \ '),' \ ') as hierarchypath
  from classstructure c
 where parent is not null
 start with parent is null
connect by prior classstructureid = parent;

HIERARCHYPATH
--------------------------------------
FLEET \ LIGHTDUTYVEHICLE
FLEET \ MEDIUMDUTYVEHICLE
ACTIVETRANSPORTATION \ FACILITYWALKWAY
ACTIVETRANSPORTATION \ TRAIL
ACTIVETRANSPORTATION \ SIDEWALK
ACTIVETRANSPORTATION \ SIDEWALK \ SDWRAMP

编辑 1:

我在写完这个问题后意识到我应该包括层次结构第一级的行。

这是@Barbaros 查询的更新版本。我删除了 WHERE 子句。

select ltrim(sys_connect_by_path(classificationid, ' \ '),' \ ') as hierarchypath
from maximo.classstructure
start with parent is null
connect by prior classstructureid = parent;

编辑 2:

对于奖励积分,这里是一个查询版本,其中还包括 Maximo 的 USE WITH 对象(按并串联分组):

select 
    ltrim(sys_connect_by_path(cl.classificationid, ' \ '),' \ ') as hierarchypath,
    cl.classstructureid,
    cl.description,
    uw.usewith
from 
    maximo.classstructure cl
left join
    (
    select 
        classstructureid, 
        listagg(objectname,', ') within group(order by objectname) as usewith
    from 
        maximo.classusewith
    group by 
        classstructureid
    ) uw
    on cl.classstructureid = uw.classstructureid
start with parent is null
connect by prior cl.classstructureid = parent
order by
    hierarchypath


编辑 3:

附带说明一下,这里是如何在 子查询 中使用 USEWITH 进行分组(对于我们不能使用 JOIN 子句的情况,只能使用 WHERE 子句) .

当然,子查询性能比正确的连接差很多。我们希望尽可能使用连接而不是子查询。

select 
    cl.classstructureid,
    cl.description,
   
    (select 
        listagg(objectname,', ') within group(order by objectname) as usewith
    from 
        maximo.classusewith
    group by 
        classstructureid
    having 
        classstructureid = cl.classstructureid
    ) as usewith

from 
    maximo.classstructure cl
order by
    description

同样的查询也可以应用于 Maximo asset hiearchy(不仅仅是分类):

select 
    assetnum,
    ltrim(sys_connect_by_path(assetnum, ' \ '),' \ ') as path,
    level
from 
    maximo.asset
start with parent is null
connect by prior assetnum = parent

我还添加了一个 LEVEL 列,它为我们提供了 级别数