2011-03-18 88 views
6

我對菜單的hierarchyID和UserRights有問題。例如,我只想爲用戶提供4級權限,我的QUERY應自動從4級子級選擇所有父級。 如何做到這一點?HierarchyID如何讓孩子的所有父母

你明白我的問題嗎?我只想要一個孩子的所有父母(祖先)。

電賀曼努埃爾

+0

這個問題也已經在這裏找到答案,並擁有由西蒙·因斯提出一個相當有趣的方法。 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

+0

你應該給表中的列與一些樣本數據,然後提供您想要實現的輸出。這將有助於人們給出更好的答案。另外,如果您已經嘗試過某些東西,則應該提供SQL代碼。 – JamieSee 2017-09-14 23:18:59

回答

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

像這樣的事情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 
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 
0
Declare @hid hierarchyid=0x5D10 -- Child hierarchy id 

SELECT 
* 
FROM 
    dbo.TableName 
WHERE 
    @hid.IsDescendantOf(ParentHierarchyId) = 1  
+1

不符合OP規定的基本條件,讓所有的父母都從孩子那裏得到。這從父母獲得所有孩子。 – JamieSee 2017-09-14 23:12:46

相關問題