递归以获得完整的层次结构

时间:2014-12-12 10:03:42

标签: sql sql-server hierarchical-data sql-server-2014

我有两个表,一个存储一个techtree并具有以下结构:

**TECHTREE TABLE**
ID - int
ParentID - int (relational to ID)
name - varchar

和数据表' UserSkills'具有以下结构:

**USERSKILLS TABLE**
TECHID - int (relational to TECHTREE.ID)
SKILLLEVEL - varchar
LOGIN - varchar

给出以下技术树数据

ID  ParentID  Name
1   24        Microsoft
2   1         Server
3   1         Hyper-V
4   24        VMWare
5   4         vSphere
7   2         Betriebssystem
8   2         AD, DNS, DHCP
9   2         PKI
14  5         4.x
15  5         5.x
16  4         VDI/View
17  4         SRM
18  24        Symantec
19  18        Backup Exec
20  19        2010
21  19        2012
22  18        SEP
23  24        Citrix
24  NULL      Data Center SW
25  NULL      Data Center HW
26  NULL      IPT
27  NULL      Networking
28  NULL      Security
29  NULL      Misc

并关注用户技能数据

TechID   SkillLevel     Login
7        Expert         mike
8        Basics         mike
9        Basics         peter   
67       Expert         peter
31       Expert         peter
32       Support        chris
33       Expert         peter
34       Expert         chris
35       Expert         adam
36       Support        adam
65       Support        adam
66       Expert         tom
78       Expert         tom
75       Basics         tom
76       Expert         tom
77       Expert         tom

现在我想从techtree表中获取 userskill 表中的行,包括完整层次结构。 结果应该看起来像

ID  LVL0              LVL1          LVL2      LVL3            LVL4        LVL5      LVL6    Skilllevel
7   Data Center SW    Microsoft     Server    OS                                            Expert
8   Data Center SW    Microsoft     Server    AD, DNS, DHCP                                 Basics
9   Data Center SW    Microsoft     Server    PKI                                           Basics
67  Networking                                                                              Expert                                
31  Networking                                                                              Expert                                

有谁知道如何在sql中实现这一目标?

2 个答案:

答案 0 :(得分:1)

样本数据仍然存在。现在没有ID 67或31。这已经接近了

http://sqlfiddle.com/#!6/ae330/1

我没有使用递归CTE,因为你有固定数量的级别。

WITH CTE AS
(
    SELECT
        TT.ID, TT.ParentID, TT.Name, US.SkillLevel
    FROM
        dbo.TechTree TT
        LEFT JOIN
        dbo.UserSkills US ON TT.ID = US.TechID
)
SELECT 
    COALESCE(c6.ID, c5.ID, c4.ID, c3.ID, c2.ID, c1.ID, c0.ID) AS ID,
    c0.Name AS LVL0,
    c1.Name AS LVL1,
    c2.Name AS LVL2,
    c3.Name AS LVL3,
    c4.Name AS LVL4,
    c5.Name AS LVL5,
    c6.Name AS LVL6,
    COALESCE(c6.SkillLevel, c5.SkillLevel, c4.SkillLevel, c3.SkillLevel, c2.SkillLevel, c1.SkillLevel, c0.SkillLevel) AS SkillLevel
FROM 
    CTE c0 
    LEFT JOIN
    CTE c1 ON c0.ID = c1.ParentID 
    LEFT JOIN
    CTE c2 ON c1.ID = c2.ParentID
    LEFT JOIN
    CTE c3 ON c2.ID = c3.ParentID
    LEFT JOIN
    CTE c4 ON c3.ID = c4.ParentID
    LEFT JOIN
    CTE c5 ON c4.ID = c5.ParentID
    LEFT JOIN
    CTE c6 ON c5.ID = c6.ParentID
WHERE 
    c0.ParentID IS NULL

答案 1 :(得分:0)

我实际上刚刚制定了一个可以帮助您解决此问题的解决方案。我想为我的组织树制作一个带有“路径”的字符串。所以我做了一个递归CTE来映射树中的级别:

;with orgSublevels as (
select 
name
  ,cast('head' as nvarchar(50)) as parent
  ,ID
  ,ParentID
  ,1 as levelof
  ,cast(ID as nvarchar(max)) as orgPath
from Tree
union all
select 
name
  ,parent.name as nvarchar(50)) as parent
  ,ID
  ,ParentID
  ,levelof + 1 as levelof
  ,cast(o.orgPath as nvarchar(max)) + ', '+ cast(tree.ID as nvarchar(max)) as orgPath
from orgSublevels o
join Tree on tree.ID = o.parentID
)

现在您拥有组织树的级别和路径。使用(动态)透视,您可以创建一个以级别为列的表。希望有所帮助!