我对菜单的hierarchyID和UserRights有问题。我只想给用户4级权限,我的QUery应该自动从4级孩子中选择所有父级。 怎么做?
你了解我的问题吗?我只想要一个孩子的所有父母(祖先)。
Greets Manuel
答案 0 :(得分:3)
这样的东西避免了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
答案 1 :(得分:3)
我最近一直在使用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
答案 2 :(得分: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的递归部分,而不是过滤树的最顶层节点。
希望这有帮助,
乌迪德
答案 3 :(得分:0)
Declare @hid hierarchyid=0x5D10 -- Child hierarchy id
SELECT
*
FROM
dbo.TableName
WHERE
@hid.IsDescendantOf(ParentHierarchyId) = 1