我對菜單的hierarchyID和UserRights有問題。例如,我只想爲用戶提供4級權限,我的QUERY應自動從4級子級選擇所有父級。 如何做到這一點?HierarchyID如何讓孩子的所有父母
你明白我的問題嗎?我只想要一個孩子的所有父母(祖先)。
電賀曼努埃爾
我對菜單的hierarchyID和UserRights有問題。例如,我只想爲用戶提供4級權限,我的QUERY應自動從4級子級選擇所有父級。 如何做到這一點?HierarchyID如何讓孩子的所有父母
你明白我的問題嗎?我只想要一個孩子的所有父母(祖先)。
電賀曼努埃爾
讓我們假設你有這樣的表:
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的遞歸部分,而不是過濾樹的最頂端節點。
希望這有助於
俄德
像這樣的事情avoides的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
我最近工作很多與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
Declare @hid hierarchyid=0x5D10 -- Child hierarchy id
SELECT
*
FROM
dbo.TableName
WHERE
@hid.IsDescendantOf(ParentHierarchyId) = 1
不符合OP規定的基本條件,讓所有的父母都從孩子那裏得到。這從父母獲得所有孩子。 – JamieSee 2017-09-14 23:12:46
這個問題也已經在這裏找到答案,並擁有由西蒙·因斯提出一個相當有趣的方法。 http://stackoverflow.com/questions/3119860/how-do-you-get-all-ancestors-of-a-node-using-sql-server-2008-hierarchyid乾杯, – Eric 2011-07-22 13:51:32
你應該給表中的列與一些樣本數據,然後提供您想要實現的輸出。這將有助於人們給出更好的答案。另外,如果您已經嘗試過某些東西,則應該提供SQL代碼。 – JamieSee 2017-09-14 23:18:59