Sql-Server
HierarchyID:獲取父母列表的所有後代
我有一個這樣的父 ID 列表,
100, 110, 120, 130
它是動態的並且可以更改。我想在一組中獲取指定父母的所有後代。為了獲得一個單親的孩子,我使用了這樣的查詢:WITH parent AS ( SELECT PersonHierarchyID FROM PersonHierarchy WHERE PersonID = 100 ) SELECT * FROM PersonHierarchy WHERE PersonHierarchyID.IsDescendantOf((SELECT * FROM parent)) = 1
不知道如何為多個父母做到這一點。我的第一次嘗試是寫幾個聯合之類的東西,但是我確信應該有更聰明的方法來做這件事。
SELECT * FROM PersonHierarchy WHERE PersonHierarchyID.IsDescendantOf( (SELECT PersonHierarchyID FROM PersonHierarchy WHERE PersonID = 100) ) = 1 UNION ALL SELECT * FROM PersonHierarchy WHERE PersonHierarchyID.IsDescendantOf( (SELECT PersonHierarchyID FROM PersonHierarchy WHERE PersonID = 110) ) = 1 UNION ALL ...
PS我還發現這樣的查詢來選擇可能有幫助的ID列表:
SELECT * FROM (VALUES (100), (110), (120), (130)) AS Parent(ParentID)
總而言之,我的目標是編寫接受父 ID 數組作為參數的查詢,並在一個集合中返回它們的所有後代。
實現此目的的一種方法是:
USE tempdb; CREATE TABLE dbo.PersonHierarchy ( PersonHierarchyID HierarchyID ); INSERT INTO dbo.PersonHierarchy VALUES ('/1/'); INSERT INTO dbo.PersonHierarchy VALUES ('/1/1/'); INSERT INTO dbo.PersonHierarchy VALUES ('/1/2/'); INSERT INTO dbo.PersonHierarchy VALUES ('/2/'); INSERT INTO dbo.PersonHierarchy VALUES ('/2/1/'); SELECT * FROM dbo.PersonHierarchy; DECLARE @T TABLE ( PersonHierarchyID HierarchyID ); INSERT INTO @T VALUES ('/1/'), ('/2/'); WITH parent AS ( SELECT p.PersonHierarchyID FROM dbo.PersonHierarchy p INNER JOIN @T t ON p.PersonHierarchyID = t.PersonHierarchyID ) SELECT ph.PersonHierarchyID.ToString(), parent.PersonHierarchyID.ToString() /* select only the necessary columns, do NOT use SELECT * */ FROM dbo.PersonHierarchy ph INNER JOIN parent ON ph.PersonHierarchyID.IsDescendantOf(parent.PersonHierarchyID) = 1 ORDER BY ph.PersonHierarchyID; /* always include an ORDER BY */