我有两个表,ticket
和problem
。每张票都有问题,每个问题可能有也可能没有父问题。样本数据:
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
这是我需要的结果:
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+
| 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 | |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+
假设顶层父级最多有四个后代,我如何以顶级父级的相反顺序解决问题?这就是我到目前为止所拥有的:
;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
我似乎无法弄清楚如何首先获得0级列,然后是孩子们。
答案 0 :(得分:0)
示例数据:
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;
结果: