使用t-sql
hierarchy我如何獲得所有沒有孩子(這是最後的死者)的行?Sql HierarchyId我如何得到最後的後代?
說我的表的結構是這樣的:
Id,
Name,
HierarchyId
而且具有這些行:
1, Craig,/
2, Steve, /1/
3, John, /1/1/
4, Sam, /2/
5, Matt, /2/1/
6, Chris, /2/1/1/
什麼查詢會給我約翰和克里斯?
使用t-sql
hierarchy我如何獲得所有沒有孩子(這是最後的死者)的行?Sql HierarchyId我如何得到最後的後代?
說我的表的結構是這樣的:
Id,
Name,
HierarchyId
而且具有這些行:
1, Craig,/
2, Steve, /1/
3, John, /1/1/
4, Sam, /2/
5, Matt, /2/1/
6, Chris, /2/1/1/
什麼查詢會給我約翰和克里斯?
也許有更好的方法,但這接合來完成這項工作。
declare @T table
(
ID int,
Name varchar(10),
HID HierarchyID
)
insert into @T values
(1, 'Craig', '/'),
(2, 'Steve', '/1/'),
(3, 'John', '/1/1/'),
(4, 'Sam', '/2/'),
(5, 'Matt', '/2/1/'),
(6, 'Chris', '/2/1/1/')
select *
from @T
where HID.GetDescendant(null, null) not in (select HID
from @T)
結果:
ID Name HID
----------- ---------- ---------------------
3 John 0x5AC0
6 Chris 0x6AD6
更新如果節點號未處於不間斷的序列上方2012-05-22
查詢將失敗。這是另一個應該注意的版本。
declare @T table
(
ID int,
Name varchar(10),
HID HierarchyID
)
insert into @T values
(1, 'Craig', '/'),
(2, 'Steve', '/1/'),
(3, 'John', '/1/1/'),
(4, 'Sam', '/2/'),
(5, 'Matt', '/2/1/'),
(6, 'Chris', '/2/1/2/') -- HID for this row is changed compared to above query
select *
from @T
where HID not in (select HID.GetAncestor(1)
from @T
where HID.GetAncestor(1) is not null)
既然你只需要葉子,你不需要從一個特定的祖先讓他們,這樣一個簡單的非遞歸查詢應該做的工作:
SELECT * FROM YOUR_TABLE PARENT
WHERE
NOT EXISTS (
SELECT * FROM YOUR_TABLE CHILD
WHERE CHILD.HierarchyId = PARENT.Id
)
用簡單的英語:選擇的每一行沒有孩子排。
這裏假設您的HierarchyId
是一個對於Id
的FOREIGN KEY,而不是整個「路徑」,如您的示例所示。如果不是,這可能是您應該在數據庫模型中修復的第一件事。
---編輯---
OK,下面是實際工作的MS SQL Server特定的查詢:
SELECT * FROM YOUR_TABLE PARENT
WHERE
NOT EXISTS (
SELECT * FROM YOUR_TABLE CHILD
WHERE
CHILD.Id <> PARENT.Id
AND CHILD.HierarchyId.IsDescendantOf(PARENT.HierarchyId) = 1
)
注意,IsDescendantOf
認爲任何行自身的後代,所以我們還需要CHILD.Id <> PARENT.Id
這個條件。
嗨我使用這一個,併爲我完美的作品。
CREATE TABLE [dbo].[Test]([Id] [hierarchyid] NOT NULL, [Name] [nvarchar](50) NULL)
DECLARE @Parent AS HierarchyID = CAST('/2/1/' AS HierarchyID) -- Get Current Parent
DECLARE @Last AS HierarchyID
SELECT @Last = MAX(Id) FROM Test WHERE Id.GetAncestor(1) = @Parent -- Find Last Id for this Parent
INSERT INTO Test(Id,Name) VALUES(@Parent.GetDescendant(@Last, NULL),'Sydney') -- Insert after Last Id
我相當肯定的是OP使用SQL Server 2008,這也解釋了不尋常的表現的'HierarchyID'數據類型(見http://msdn.microsoft.com/en-us/magazine/cc794278的.aspx)。 – 2011-12-19 14:01:28
@DanielPratt啊......我現在看到這個問題被重新標記爲[sql-server]。 – 2011-12-19 14:04:15
感謝您的Branko,但在我的示例中,Id字段是整數,HierarchyId是sql HierarchyId,因此無法進行比較。你是否說我需要將表格的關鍵字改爲hierarchyId? – Eric 2011-12-19 14:13:07