我对菜单的 hierarchyID 和 UserRights 有问题。例如,我只想给用户 4 级的权利,我的查询应该自动从 4 级子级中选择所有父级。这个怎么做 ?
你明白我的问题吗?我只是想要一个孩子的所有父母(祖先)。
问候曼努埃尔
我对菜单的 hierarchyID 和 UserRights 有问题。例如,我只想给用户 4 级的权利,我的查询应该自动从 4 级子级中选择所有父级。这个怎么做 ?
你明白我的问题吗?我只是想要一个孩子的所有父母(祖先)。
问候曼努埃尔
最近我一直在使用 HierarchyId 进行很多工作,我遇到了这个问题,以寻找不同问题的答案。我想我会把这个例子混在一起,因为它说明了一些事情。首先,您可以在没有递归 CTE 的情况下获得条件表达式。其次,GetDescendantOf 是包容性的,因此您不需要检查t1.NodeId = t2.NodeId
(我通常更喜欢连接而不是子查询)。这是您可以玩的完整演示:
BEGIN TRANSACTION
CREATE TABLE #HierarchyDemo
(
NodeId HIERARCHYID PRIMARY KEY NOT NULL,
Description AS NodeId.ToString(),
Depth AS NodeId.GetLevel()
)
INSERT INTO #HierarchyDemo VALUES ( HierarchyId::GetRoot() );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/1979/' AS HIERARCHYID) );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/2012/' AS HIERARCHYID) );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/2012/2/' AS HIERARCHYID) );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/1979/4/' AS HIERARCHYID) );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/2012/2/17/' AS HIERARCHYID) );
INSERT INTO #HierarchyDemo VALUES ( CAST ('/1979/4/6/' AS HIERARCHYID) );
SELECT *
FROM #HierarchyDemo;
SELECT *
FROM #HierarchyDemo startingPoint
INNER JOIN #HierarchyDemo parent
ON startingPoint.NodeId.IsDescendantOf(parent.NodeId) = 1
WHERE startingPoint.Description = '/2012/2/17/'
ROLLBACK TRANSACTION
这样的事情避免了CTE
SELECT t1.NodeId.ToString(), t1.Name
FROM (SELECT * FROM test_table2
WHERE Name = 'Node 1.1.1') t2
, test_table2 t1
WHERE
t1.NodeId = t2.NodeId OR
t2.NodeId.IsDescendantOf(t1.NodeId) = 1
假设您有这张桌子:
CREATE TABLE Hierarchy
(
CompanyNode hierarchyid NOT NULL,
CompanyId int NOT NULL,
NodeLevel AS CompanyNode.GetLevel()
CONSTRAINT PK_Hierarchy PRIMARY KEY NONCLUSTERED (CompanyNode)
)
然后你填充它,让它保存这些数据:
CompanyNode CompanyId NodeLevel
0x 1 0
0x58 2 1
0x5AC0 3 2
0x68 100 1
0x6AC0 101 2
0x6AD6 1000 3
0x6AD6B0 10000 4
0x78 20 1
0x7AC0 200 2
0x7AD6 2000 3
0x7AD6B0 20000 4
0x7AD6B580 200000 5
0x7AD6D0 20001 4
0x7ADA 2001 3
0x7ADE 2002 3
0x7B40 201 2
0x7BC0 202 2
现在你想得到 CompanyId 20001 的所有父母,我就是这样做的:
DECLARE @currentLevel smallint
SELECT @currentLevel = NodeLevel
FROM Hierarchy
WHERE CompanyId = 20001;
with tree([Path], [PathName], CompanyId, [Level])
AS
(
SELECT h.CompanyNode AS [Path],
h.CompanyNode.ToString() AS [PathName],
h.CompanyId,
@currentLevel AS [Level]
FROM Hierarchy h
WHERE h.CompanyId = 20001
UNION ALL
SELECT h.CompanyNode AS [Path],
h.CompanyNode.ToString() AS [PathName],
h.CompanyId,
CAST((t.[Level] - 1) AS smallint) AS [Level]
FROM Hierarchy h
INNER JOIN tree t ON
t.[Path].GetAncestor(1) = h.CompanyNode
WHERE h.[NodeLevel] > 0
)
SELECT * FROM TREE
order by [Path]
您可以更改 CTE 的递归部分,而不过滤树的最顶层节点。
希望这可以帮助,
奥德
Declare @hid hierarchyid=0x5D10 -- Child hierarchy id
SELECT
*
FROM
dbo.TableName
WHERE
@hid.IsDescendantOf(ParentHierarchyId) = 1