SQL 服务器层次结构 ID 搜索记录并在结果中包含所有相关父项
SQL Server Hierarchy ID search for records and include all related parents in result
我已经使用 SQL 服务器层次结构 ID 设置了产品类别 table,我想在 returns 的 CMS 中创建一个自动完成下拉列表搜索匹配的类别,但不仅显示匹配的类别名称,还会显示它的 hierarchy/path,例如
用户开始搜索 "Cat" 并在自动完成中看到
- 宠物用品 > 猫
- 宠物用品 > 猫 > 猫粮
- 宠物用品 > 毛毛虫
- 宠物活动 > 狗狗 > 捕捉游戏
有没有简单的方法可以做到这一点?我发现的示例侧重于选择首先选择的单个特定节点的父节点,但我找不到任何选择多个节点然后为匹配节点选择所有父节点的示例。
一旦我从数据库中检索到结果,我很乐意将结果整理成上面概述的格式,但获取数据似乎是棘手的部分。
我正在使用 SQL Server 2012(不过我认为这并不重要)
这是我的架构(没什么特别的):
CREATE TABLE [dbo].[Category] (
[CategoryId] INT IDENTITY (1, 1) NOT NULL,
[PrimaryProductId] INT NULL,
[CategoryNode] [sys].[hierarchyid] NOT NULL,
[CategoryString] AS ([CategoryNode].[ToString]()) PERSISTED,
[CategoryLevel] AS ([CategoryNode].[GetLevel]()) PERSISTED,
[Title] NVARCHAR (50) NOT NULL,
[IsActive] BIT DEFAULT ((1)) NOT NULL,
CONSTRAINT [Category_CategoryId_PK] PRIMARY KEY CLUSTERED ([CategoryId] ASC),
CONSTRAINT [Category_Product_PrimaryProductId] FOREIGN KEY (PrimaryProductId) REFERENCES [dbo].[Product](ProductId),
UNIQUE NONCLUSTERED ([CategoryNode] ASC)
);
这是单行父级的示例:
DECLARE @person hierarchyid
SELECT @person = Id
FROM dbo.HierachyTable
WHERE [Name] = 'Joe Blow';
SELECT
Id, Id.ToString() AS [Path],
Id.GetLevel() AS [Level],
Id.GetAncestor(1),
Name
FROM
dbo.HierarchyTable
WHERE
@person.IsDescendantOf(Id) = 1
这是一个 table 值函数,给定一个 hierarchyid,将 return hierarchyid 的所有祖先。
alter function dbo.GetAllAncestors(@h hierarchyid, @ReturnSelf bit)
returns table
as return
select @h.GetAncestor(n.Number) as h
from dbo.Numbers as n
where n.Number < @h.GetLevel()
union all
select @h
where @ReturnSelf = 1
go
其中数字 table 只是一个计数 table(google 如果您从未听说过它)。对于您的 "Joe Blow" 示例,这应该有效:
SELECT t.*
FROM dbo.HierarchyTable as h
cross apply dbo.GetAllAncestors(h.CategoryNode, 1) as a
join dbo.HierarchyTable as t
on a.h = t.CategoryNode
WHERE h.[Name] = 'Joe Blow';
我已经使用 SQL 服务器层次结构 ID 设置了产品类别 table,我想在 returns 的 CMS 中创建一个自动完成下拉列表搜索匹配的类别,但不仅显示匹配的类别名称,还会显示它的 hierarchy/path,例如
用户开始搜索 "Cat" 并在自动完成中看到
- 宠物用品 > 猫
- 宠物用品 > 猫 > 猫粮
- 宠物用品 > 毛毛虫
- 宠物活动 > 狗狗 > 捕捉游戏
有没有简单的方法可以做到这一点?我发现的示例侧重于选择首先选择的单个特定节点的父节点,但我找不到任何选择多个节点然后为匹配节点选择所有父节点的示例。
一旦我从数据库中检索到结果,我很乐意将结果整理成上面概述的格式,但获取数据似乎是棘手的部分。
我正在使用 SQL Server 2012(不过我认为这并不重要)
这是我的架构(没什么特别的):
CREATE TABLE [dbo].[Category] (
[CategoryId] INT IDENTITY (1, 1) NOT NULL,
[PrimaryProductId] INT NULL,
[CategoryNode] [sys].[hierarchyid] NOT NULL,
[CategoryString] AS ([CategoryNode].[ToString]()) PERSISTED,
[CategoryLevel] AS ([CategoryNode].[GetLevel]()) PERSISTED,
[Title] NVARCHAR (50) NOT NULL,
[IsActive] BIT DEFAULT ((1)) NOT NULL,
CONSTRAINT [Category_CategoryId_PK] PRIMARY KEY CLUSTERED ([CategoryId] ASC),
CONSTRAINT [Category_Product_PrimaryProductId] FOREIGN KEY (PrimaryProductId) REFERENCES [dbo].[Product](ProductId),
UNIQUE NONCLUSTERED ([CategoryNode] ASC)
);
这是单行父级的示例:
DECLARE @person hierarchyid
SELECT @person = Id
FROM dbo.HierachyTable
WHERE [Name] = 'Joe Blow';
SELECT
Id, Id.ToString() AS [Path],
Id.GetLevel() AS [Level],
Id.GetAncestor(1),
Name
FROM
dbo.HierarchyTable
WHERE
@person.IsDescendantOf(Id) = 1
这是一个 table 值函数,给定一个 hierarchyid,将 return hierarchyid 的所有祖先。
alter function dbo.GetAllAncestors(@h hierarchyid, @ReturnSelf bit)
returns table
as return
select @h.GetAncestor(n.Number) as h
from dbo.Numbers as n
where n.Number < @h.GetLevel()
union all
select @h
where @ReturnSelf = 1
go
其中数字 table 只是一个计数 table(google 如果您从未听说过它)。对于您的 "Joe Blow" 示例,这应该有效:
SELECT t.*
FROM dbo.HierarchyTable as h
cross apply dbo.GetAllAncestors(h.CategoryNode, 1) as a
join dbo.HierarchyTable as t
on a.h = t.CategoryNode
WHERE h.[Name] = 'Joe Blow';