2014-12-12 2 views
0

У меня есть две таблицы, одна хранит TechTree и имеет следующую структуру:рекурсии, чтобы получить полную иерархию

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

и А DataTable «UserSkills» со следующей структурой:

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

Предоставленная следующие данные TechTree

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 

и следующие данные userskills

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 

Теперь я хочу, чтобы получить строки из userskill таблицы включая полной иерархии из таблицы TechTree. Результат должен выглядеть

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 Server?

+1

Можете ли вы подготовить демоверсию SQL FIddle, пожалуйста? И сколько уровней вы ожидаете? – gbn

+0

Я ожидаю максимум 5 уровней. Скрипка на пути. – Mike246912

+0

@ Mike246912 в вашем примере, как вы получаете основы, когда ID = 9, поскольку в записи PKI нет каких-либо навыков, связанных с ним? –

ответ

1

Данные образца все еще сломаны. Сейчас нет ID 67 или 31. Это уже близко, хотя

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

Я не использовал рекурсивный КТР, потому что у вас есть определенное количество уровней.

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 
+0

Большое спасибо за вашу помощь! Это точно так, как должно выглядеть. Никогда не видел «COALESCE», прежде чем ... должен узнать немного больше ...: -] – Mike246912

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 
) 

Теперь у вас есть уровни и путь вашего organisationtree. Используя (динамический) опорный стержень, вы можете создать таблицу с уровнями в виде столбцов. Надеюсь, это поможет!

+0

Большое спасибо! :-) – Mike246912

Смежные вопросы