设置:
MyTable (
NodeId varchar(10),
ParentNodeId varchar(10),
NodeName varchar(50)
)
NodeId不是数字,可以采用任何形式。大多数是Z123456,但有些是12345。
我想使用SqlServer HierarchyId数据类型来满足我的分层需求。
问题:
我可以使用CTE生成我的层次结构与节点和父节点,但我需要一个路径传递给hierarchyid :: Parse() - 不幸的是,Z123456形式的nodeid不解析。如果NodeId和ParentNodeId是行id整数,我会打包并把我的火车赶回家去看我可爱的妻子,但相反,我在这里盯着3360 x 1050分辨率。
我正在使用CTE生成我的层次结构(我也可以在CTE中创建一个路径)然后我附加行号以给我我唯一的整数id但是我将不得不重新运行分层CTE使用生成的ID生成我的路径。
;with o as (
select n.ParentNodeID, n.nodeid, n.NodeName, 1 as [level]
from Mytable n where n.ParentNodeID is null
union all
select n.ParentNodeID, n.nodeid, n.NodeName, o.[level] + 1 as [Level]
from MyTable n inner join o on n.ParentNodeID = o.NodeID
)
select NodeID, ParentNodeID, NodeDescription
, ROW_NUMBER() over (order by [level]) as hNodeId
from o
问题:
无论如何我可以在表单层次结构中实现路径:Id :: Parse()将接受一个CTE吗?例如/ 1/2/3 /
TIA
答案 0 :(得分:3)
with C as
(
select T.NodeId,
T.ParentNodeId,
cast('/'+cast(row_number() over(order by T.NodeId) as varchar(10)) as varchar(max)) as HID
from MyTable as T
where T.ParentNodeId is null
union all
select T.NodeId,
T.ParentNodeId,
C.HID+'/'+cast(row_number() over(order by T.NodeId) as varchar(10))
from MyTable as T
inner join C
on T.ParentNodeId = C.NodeId
)
select NodeId,
ParentNodeId,
HID,
hierarchyId::Parse(HID+'/')
from C
order by HID
<强>更新强>
一些研究表明,不允许在递归CTE中使用分析函数。它适用于我的测试,但如果我能想到替代解决方案,我会更新这个答案。
Omission about analytic and aggregate functions in CTEs
更新2:
显然,这个解决方案可以安全使用,因为它在MSDN上有记录
WITH common_table_expression (Transact-SQL)
CTE的递归部分中的分析和聚合函数是 应用于当前递归级别的集合而不是集合 对于CTE。像ROW_NUMBER这样的函数只对子集有效 数据通过当前递归级别而不是整个传递给它们 数据集用于CTE的递归部分