Sql HierarchyId如何获取最后的后代?
使用t-sql Id如何获取没有子级的所有行(即最后一个decentant) 假设我的表的结构如下:Sql HierarchyId如何获取最后的后代?,sql,sql-server,hierarchyid,Sql,Sql Server,Hierarchyid,使用t-sql Id如何获取没有子级的所有行(即最后一个decentant) 假设我的表的结构如下: Id, Name, HierarchyId 有以下几行: 1, Craig, / 2, Steve, /1/ 3, John, /1/1/ 4, Sam, /2/ 5, Matt, /2/1/ 6, Chris, /2/1/1/ 什么查询会给我John和Chris?因为您只需要leaf,而不需要从特定的祖先那里获取它们,像这样一个简单的非递归查询应该可以完成这项工作: SELECT
Id,
Name,
HierarchyId
有以下几行:
1, Craig, /
2, Steve, /1/
3, John, /1/1/
4, Sam, /2/
5, Matt, /2/1/
6, Chris, /2/1/1/
什么查询会给我John和Chris?因为您只需要leaf,而不需要从特定的祖先那里获取它们,像这样一个简单的非递归查询应该可以完成这项工作:
SELECT * FROM YOUR_TABLE PARENT
WHERE
NOT EXISTS (
SELECT * FROM YOUR_TABLE CHILD
WHERE CHILD.HierarchyId = PARENT.Id
)
简体中文:选择没有子行的每一行
这假设您的HierarchyId是指向该Id的外键,而不是示例中所示的整个路径。如果不是,这可能是您应该在数据库模型中修复的第一件事
--编辑--
好的,下面是实际工作的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
)
请注意,isDescendatof将任何一行视为其自身的后代,因此我们还需要条件中的CHILD.Id PARENT.Id。也许有更好的方法,但这可以完成这项工作
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)
嗨,我用这个,非常适合我
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数据类型,这就解释了这种不寻常的表示形式。请参见。@DanielPratt Ahh。。。现在我看到问题被重新标记为[sql server]。感谢您的回复,但在我的示例中,Id字段是一个整数,而HierarchyId是一个sql HierarchyId,因此无法对它们进行比较。您是说我需要将表的键更改为hierarchyId吗?@EricNeifert我假设您使用的是经典设计来表示关系数据库中的分层数据,而不是MS SQL Server特定的机制。不幸的是,我对特定于MS SQL Server的机制还不太熟悉,因此无法建议您是否实际进行切换,但似乎同样的基本思想也可以应用于MS SQL Server—请参阅。