2016-04-05 19 views
1

Ich habe zwei Tabellen, ticket und problem. Jedes Ticket hat ein Problem und jedes Problem kann ein Elternproblem haben oder nicht. Beispieldaten:Verwenden eines CTE zum Auflisten der Eltern als Spalten

create table #problem (problem_type_id int, problem_type_name varchar(32), parent_id int) 
insert #problem 
select 1, 'Change Request', NULL union 
select 5, 'Level 1', 1 union 
select 10, 'Software', 5 union 
select 15, 'Applications', 10 union 
select 20, 'Update', 15 union 
select 6, 'Level 2', 1 union 
select 11, 'Hardware', 6 union 
select 16, 'Install', 11 

create table #ticket (ticket_id int, problem_type_id int) 
insert #ticket 
select 1, 20 union 
select 2, 16 

Hier ist das Ergebnis, das ich brauche:

+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+ 
| ticket_id | problem_level_1 | problem_level_2 | problem_level_3 | problem_level_4 | problem_level_5 | 
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+ 
| 1   | Change Request | Level 1   | Software  | Applications | Update   | 
| 2   | Change Request | Level 2   | Hardware  | Install   |     | 
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+ 

Unter der Annahme, dass es höchstens vier Nachkommen von einem Top-Level-Eltern sein wird, wie kann ich die Probleme in der umgekehrten Reihenfolge erhalten mit der oberste Elternteil zuerst? Hier ist, was ich bisher:

;with probs (parent_id, problem_type_id, problem_type_name, level) 
as 
(
    -- anchor member definition 
    select parent_id, problem_type_id, problem_type_name, 0 as level 
    from #problem 
    where parent_id is null 
    union all 
    -- recursive member definition 
    select a.parent_id, a.problem_type_id, a.problem_type_name, level + 1 
    from #problem a 
    join probs as b on b.problem_type_id = a.parent_id 
) 
select t.ticket_id, 
p1.level, /* p1.problem_type_id, */ p1.problem_type_name, 
p2.level, /* p2.problem_type_id, */ p2.problem_type_name, 
p3.level, /* p3.problem_type_id, */ p3.problem_type_name, 
p4.level, /* p4.problem_type_id, */ p4.problem_type_name, 
p5.level, /* p5.problem_type_id, */ p5.problem_type_name 
from #ticket t 
join probs p1 on p1.problem_type_id = t.problem_type_id 
left join probs p2 on p2.problem_type_id = p1.parent_id and p2.level = p1.level - 1 
left join probs p3 on p3.problem_type_id = p2.parent_id and p3.level = p2.level - 1 
left join probs p4 on p4.problem_type_id = p3.parent_id and p4.level = p3.level - 1 
left join probs p5 on p5.problem_type_id = p4.parent_id and p5.level = p4.level - 1 
order by t.ticket_id 

Ich kann nicht scheinen, um herauszufinden, wie die Ebene 0 Spalten zuerst erhalten, dann die Kinder.

Antwort

0

Sie sind fast da. Sie können diese mit PIVOT wie so erreichen:

SAMPLE DATA:

CREATE TABLE #problem(problem_type_id INT 
       , problem_type_name VARCHAR(32) 
       , parent_id   INT); 

INSERT INTO #problem 
     SELECT 1 
      , 'Change Request' 
      , NULL 
     UNION 
     SELECT 5 
      , 'Level 1' 
      , 1 
     UNION 
     SELECT 10 
      , 'Software' 
      , 5 
     UNION 
     SELECT 15 
      , 'Applications' 
      , 10 
     UNION 
     SELECT 20 
      , 'Update' 
      , 15 
     UNION 
     SELECT 6 
      , 'Level 2' 
      , 1 
     UNION 
     SELECT 11 
      , 'Hardware' 
      , 6 
     UNION 
     SELECT 16 
      , 'Install' 
      , 11; 

CREATE TABLE #ticket(ticket_id  INT 
       , problem_type_id INT); 

INSERT INTO #ticket 
     SELECT 1 
      , 20 
     UNION 
     SELECT 2 
      , 16; 

QUERY:

;WITH probs(parent_id 
     , problem_type_id 
     , problem_type_name 
     , level) 
    AS (
    -- anchor member definition 
    SELECT parent_id 
     , problem_type_id 
     , problem_type_name 
     , 0 AS level 
    FROM  #problem 
    WHERE parent_id IS NULL 
    UNION ALL 
    -- recursive member definition 
    SELECT a.parent_id 
     , a.problem_type_id 
     , a.problem_type_name 
     , level + 1 
    FROM #problem a 
      JOIN probs AS b ON b.problem_type_id = a.parent_id) 
    SELECT t.ticket_id 
     , p1.level 

      /* p1.problem_type_id, */ 

     , p1.problem_type_name 
    INTO #preResult 
    FROM  #ticket t 
      JOIN probs p1 ON p1.problem_type_id = t.problem_type_id 
      LEFT JOIN probs p2 ON p2.problem_type_id = p1.parent_id 
          AND p2.level = p1.level - 1 
      LEFT JOIN probs p3 ON p3.problem_type_id = p2.parent_id 
          AND p3.level = p2.level - 1 
      LEFT JOIN probs p4 ON p4.problem_type_id = p3.parent_id 
          AND p4.level = p3.level - 1 
      LEFT JOIN probs p5 ON p5.problem_type_id = p4.parent_id 
          AND p5.level = p4.level - 1 
    UNION 
    SELECT t.ticket_id 
     , p2.level 

      /* p2.problem_type_id, */ 

     , p2.problem_type_name 
    FROM  #ticket t 
      JOIN probs p1 ON p1.problem_type_id = t.problem_type_id 
      LEFT JOIN probs p2 ON p2.problem_type_id = p1.parent_id 
          AND p2.level = p1.level - 1 
      LEFT JOIN probs p3 ON p3.problem_type_id = p2.parent_id 
          AND p3.level = p2.level - 1 
      LEFT JOIN probs p4 ON p4.problem_type_id = p3.parent_id 
          AND p4.level = p3.level - 1 
      LEFT JOIN probs p5 ON p5.problem_type_id = p4.parent_id 
          AND p5.level = p4.level - 1 
    UNION 
    SELECT t.ticket_id 
     , p3.level 

      /* p3.problem_type_id, */ 

     , p3.problem_type_name 
    FROM  #ticket t 
      JOIN probs p1 ON p1.problem_type_id = t.problem_type_id 
      LEFT JOIN probs p2 ON p2.problem_type_id = p1.parent_id 
          AND p2.level = p1.level - 1 
      LEFT JOIN probs p3 ON p3.problem_type_id = p2.parent_id 
          AND p3.level = p2.level - 1 
      LEFT JOIN probs p4 ON p4.problem_type_id = p3.parent_id 
          AND p4.level = p3.level - 1 
      LEFT JOIN probs p5 ON p5.problem_type_id = p4.parent_id 
          AND p5.level = p4.level - 1 
    UNION 
    SELECT t.ticket_id 
     , p4.level 

      /* p4.problem_type_id, */ 

     , p4.problem_type_name 
    FROM  #ticket t 
      JOIN probs p1 ON p1.problem_type_id = t.problem_type_id 
      LEFT JOIN probs p2 ON p2.problem_type_id = p1.parent_id 
          AND p2.level = p1.level - 1 
      LEFT JOIN probs p3 ON p3.problem_type_id = p2.parent_id 
          AND p3.level = p2.level - 1 
      LEFT JOIN probs p4 ON p4.problem_type_id = p3.parent_id 
          AND p4.level = p3.level - 1 
      LEFT JOIN probs p5 ON p5.problem_type_id = p4.parent_id 
          AND p5.level = p4.level - 1 
    UNION 
    SELECT t.ticket_id 
     , p5.level 

      /* p5.problem_type_id, */ 

     , p5.problem_type_name 
    FROM #ticket t 
      JOIN probs p1 ON p1.problem_type_id = t.problem_type_id 
      LEFT JOIN probs p2 ON p2.problem_type_id = p1.parent_id 
          AND p2.level = p1.level - 1 
      LEFT JOIN probs p3 ON p3.problem_type_id = p2.parent_id 
          AND p3.level = p2.level - 1 
      LEFT JOIN probs p4 ON p4.problem_type_id = p3.parent_id 
          AND p4.level = p3.level - 1 
      LEFT JOIN probs p5 ON p5.problem_type_id = p4.parent_id 
          AND p5.level = p4.level - 1; 

SELECT ticket_id, problem_level_1=[0] 
      , problem_level_2=[1] 
      , problem_level_3=[2] 
      , problem_level_4=[3] 
      , problem_level_5=[4] 
FROM 
     (SELECT ticket_id 
      , level 
      , problem_type_name 
     FROM #preResult) AS p PIVOT(MAX(problem_type_name) FOR [level] IN([0] 
                  , [1] 
                  , [2] 
                  , [3] 
                  , [4])) AS unpvt; 

ERGEBNIS:

enter image description here

Verwandte Themen