微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

生成分层路径 (SQL Server)

如何解决生成分层路径 (SQL Server)

我有一张 classstructure 表:

create table classstructure (classstructureid int,classificationid varchar(25),parent int);

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


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
FLEET \ LIGHTDUTYVEHICLE
FLEET \ MEDIUMDUTYVEHICLE 

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

如何使用 sql 执行此操作?

解决方法

简短回答:这可以使用递归 CTE 来完成。这是我在 StackOverflow 上回答这个问题的另一个答案:Account Hierarchy Salesforce Accounts - SQL Server

详细说明:您的数据结构是分层数据存储在数据库中的经典方式。递归 CTE 将从某个点开始并递归循环,直到条件不再为真(找到所有孩子),因此得名;递归的。有一些免责声明,例如递归的限制(它执行多少轮),但如果需要,可以减轻这种限制。

,

这将是一个标准的递归 CTE。 CTE 非常适合中小型层次结构,但是,如果您的层次结构很大,那么还有其他使用临时表的技术可以提高性能。

注意:HierID 列是可选的。它只是提供了一个适当的顺序

示例或dbFiddle

;with cteP as (
      Select [CLASSSTRUCTUREID],[Parent],[CLASSIFICATIONID],[HIERARCHYPATH] = convert(varchar(500),[CLASSIFICATIONID]),[HierID]        = convert(hierarchyid,concat('/',[CLASSSTRUCTUREID],'/'))
      From   classstructure 
      Where  [Parent] is null
      Union  All
      Select [CLASSSTRUCTUREID]  = r.[CLASSSTRUCTUREID],[Parent]            = r.[Parent],[CLASSIFICATIONID]  = r.[CLASSIFICATIONID],[HIERARCHYPATH]     = convert(varchar(500),concat(p.[HIERARCHYPATH],' \ ',r.[CLASSIFICATIONID])),[HierID]            = convert(hierarchyid,concat(p.HierID.ToString(),r.[CLASSSTRUCTUREID],'/'))
      From   classstructure  r
      Join   cteP p on r.[Parent]  = p.[CLASSSTRUCTUREID])
Select [CLASSSTRUCTUREID],[HIERARCHYPATH]
 From cteP A
 Order by [HierID]

结果

enter image description here

就个人而言,我喜欢在最终结果中包含层次结构 LEVEL。在最后的 SELECT 中,您可以包括:

...
[Level]   = HierID.GetLevel()
...
,

给你:

with CTE_Rec as
(
    select 
        cast(classificationid as varchar(500)) classificationid,classstructureid 
    from classstructure 
    where parent is null
    
    union All
    
    Select 
        cast(b.classificationid+' \ '+a.classificationid as varchar(500)),a.classstructureid
    from classstructure a 
    inner join CTE_REC b on b.classstructureid = a.parent 
) 
Select 
    classificationid 
from CTE_Rec
order by classificationid

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。