我有一个查询,用于识别具有父关系的树中的节点。这个查询有什么问题?即使我有内部节点,也不会执行相应的case语句。我总是以Leaf或Root节点获得结果。永远不要在输出中获得内心。我可能做错了什么?
WITH CTE(N, P, [Level]) AS ( SELECT N, P, 1 FROM BST B WHERE P IS NULL UNION ALL SELECT B.N, B.P, [Level] + 1 FROM BST B JOIN CTE ON B.P = CTE.N ) SELECT N, CASE WHEN [Level] = 1 Then 'Root' WHEN [Level] < MAX([Level]) AND [Level] > 1 THEN 'Inner' WHEN [Level] = MAX([Level]) THEN 'Leaf' END FROM CTE GROUP BY N, [Level] ORDER BY N ASC;
示例输入
N P
1 2
3 2
6 8
9 8
2 5
8 5
5 NULL
示例输出
1 Leaf
2 Inner
3 Leaf
5 Root
6 Leaf
8 Inner
9 Leaf
答案 0 :(得分:4)
Why build the hier? Just a note, if this is a Jagged Hierarchy, the Max(Level) will not necessarily work. For example, a leaf node is a level 3 but the max level is 6.
Declare @YourTable table (N int,P int)
Insert Into @YourTable values
(1, 2),
(3, 2),
(6, 8),
(9, 8),
(2, 5),
(8, 5),
(5, NULL)
Select A.*
,Lvl = case when A.P is null then 'Root' else case when B.P is null then 'Leaf' else 'Inner' end end
From @YourTable A
Left Join (Select Distinct P from @YourTable) B on A.N=B.P
Returns
N P Lvl
1 2 Leaf
3 2 Leaf
6 8 Leaf
9 8 Leaf
2 5 Inner
8 5 Inner
5 NULL Root
答案 1 :(得分:2)
You can use the following query:
WITH CTE(N, P, [Level])
AS
(
SELECT N AS Node, N AS P, 1 as Level
FROM BST B
WHERE P IS NULL
UNION ALL
-- Propagate parent to all subsequent nodes
SELECT B.N, CTE.P, Level = [Level] + 1
FROM BST B
JOIN CTE ON B.P = CTE.N
)
SELECT N,
CASE
WHEN [Level] = 1 THEN 'Root'
WHEN [Level] > 1 AND [Level] < MAX([Level]) OVER (PARTITION BY P) THEN 'Inner'
WHEN [Level] = MAX([Level]) OVER (PARTITION BY P) THEN 'Leaf'
END
FROM CTE
ORDER BY N ASC;
The idea is to propagate the root node down to all other nodes, so that we can apply windowed version of MAX
with a partition by parent node clause.
答案 2 :(得分:1)
您已在level
中添加了Group by
,因此您无法从所有记录中获得max
级别
您可以使用Max Over()
窗口聚合函数
这是一种方式
SELECT N,
CASE
WHEN [Level] = 1 THEN 'Root'
WHEN [Level] < Max([Level]) over()
AND [Level] > 1 THEN 'Inner'
WHEN [Level] = Max([Level]) over() THEN 'Leaf'
END
FROM CTE
ORDER BY N ASC;