CTE 递归查询基于子作为参数获取子祖先(自下而上)
CTE Recursive Query getting Child Ancestors based on Child as parameter (bottom-up)
我有一个层次结构 Table。我想要做的是检索基于 AgentID 的 table 层次结构作为 parameter.so,return 结果应该按降序排列。我在网上找到的大多数示例只是展示了如何根据父级作为参数检索层次结构 table。
下面是我可以用来检索 Child/Parent/Parent.. 层次结构 的最接近的示例。
但是如何使用 AgentID 作为参数来获取自下而上的层次结构?
;WITH rCTE AS
(
SELECT AgentID ,
RootID ,
CAST(AgentID AS NVARCHAR(MAX)) AS PathIDs,
CAST(AgentName AS NVARCHAR(MAX)) AS PathText,
CAST(IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM TblHierarchy r WHERE NOT EXISTS (SELECT * FROM TblHierarchy n WHERE r.AgentID = n.RootID )
UNION ALL
SELECT n.AgentID ,
n.RootID ,
r.PathIDs + '>' + CAST(n.AgentID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '>' + n.AgentName AS PathText,
r.PathCost + CAST(n.IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM rCTE r
INNER JOIN dbo.TblHierarchy n ON r.RootID = n.AgentID
)
SELECT PathIDs ,
PathText ,
PathCost
FROM rCTE r
WHERE r.RootID =0--IS NULL
ORDER BY PathCost
option (maxrecursion 0)
Table 样本;
CREATE TABLE [dbo].[TblHierarchy](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AgentID] [int] NULL,
[AgentName] [varchar](50) NULL,
[RootID] [int] NULL,
[IntroducerID] [int] NULL,
[Description] [varchar](50) NULL
) ON [PRIMARY]
数据样本:
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (1, 1, N'Toh', 0, 0, N'', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (2, 2, N'Man', 1, 1, N'Child of Toh', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (3, 3, N'Rul', 1, 1, N'Child of Toh', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (4, 4, N'Rafiq', 2, 2, N'Child of Man', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (5, 5, N'Paan', 2, 2, N'Child of Man', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7857, 6, N'TohChild0', 3, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7858, 7, N'TohChild1', 3, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7859, 8, N'TohChild2', 4, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7860, 9, N'TohChild3', 4, 1, NULL, NULL)
这是此 CTE 查询的当前结果
255>127>63>31>15>7>3>1
254>127>63>31>15>7>3>1
253>126>63>31>15>7>3>1
结果是我想要的,但是这个太笼统了。我如何通过使用 AgentID 作为 参数 来获得这样的结果。因此,结果将只有 return 一行。
编辑
RootID 是父级,AgentID 是子级。我想要一个自下而上的层次结构,意味着特定 AgentID 的所有父级
假设 AgentID = 327
所以,我的预期结果将是 327>163>81>40>20>10>5>2>1
提前致谢!
递归 CTE 有两部分:
- 递归种子。这是联合之上的第一个查询,您可以在其中设置迭代的起点。您的起点是 select 任何
agentid
不是 rootid
- 递归项。这是一次又一次被调用的查询,直到连接条件失败,表示该特定分支的递归结束。
因为您只想获得特定 agentid
的结果,而不是 - 任何 agentid
不是 rootid
的结果 - 就像您目前拥有的那样,然后更改 WHERE
该递归种子上的子句:
WITH rCTE
AS (
SELECT AgentID,
RootID,
CAST(AgentID AS NVARCHAR(MAX)) AS PathIDs,
CAST(AgentName AS NVARCHAR(MAX)) AS PathText,
CAST(IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM TblHierarchy r
WHERE AgentID = 327
UNION ALL
SELECT n.AgentID,
n.RootID,
r.PathIDs + '>' + CAST(n.AgentID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '>' + n.AgentName AS PathText,
r.PathCost + CAST(n.IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM rCTE r
INNER JOIN dbo.TblHierarchy n ON r.RootID = n.AgentID
)
SELECT PathIDs,
PathText,
PathCost
FROM rCTE r
WHERE r.RootID = 0 --IS NULL
作为第二个选项,您还可以将 select 的 SELECT 语句从递归 CTE 更改为 WHERE rootID = 0 AND pathIDs like '327%'
我有一个层次结构 Table。我想要做的是检索基于 AgentID 的 table 层次结构作为 parameter.so,return 结果应该按降序排列。我在网上找到的大多数示例只是展示了如何根据父级作为参数检索层次结构 table。
下面是我可以用来检索 Child/Parent/Parent.. 层次结构 的最接近的示例。 但是如何使用 AgentID 作为参数来获取自下而上的层次结构?
;WITH rCTE AS
(
SELECT AgentID ,
RootID ,
CAST(AgentID AS NVARCHAR(MAX)) AS PathIDs,
CAST(AgentName AS NVARCHAR(MAX)) AS PathText,
CAST(IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM TblHierarchy r WHERE NOT EXISTS (SELECT * FROM TblHierarchy n WHERE r.AgentID = n.RootID )
UNION ALL
SELECT n.AgentID ,
n.RootID ,
r.PathIDs + '>' + CAST(n.AgentID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '>' + n.AgentName AS PathText,
r.PathCost + CAST(n.IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM rCTE r
INNER JOIN dbo.TblHierarchy n ON r.RootID = n.AgentID
)
SELECT PathIDs ,
PathText ,
PathCost
FROM rCTE r
WHERE r.RootID =0--IS NULL
ORDER BY PathCost
option (maxrecursion 0)
Table 样本;
CREATE TABLE [dbo].[TblHierarchy](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AgentID] [int] NULL,
[AgentName] [varchar](50) NULL,
[RootID] [int] NULL,
[IntroducerID] [int] NULL,
[Description] [varchar](50) NULL
) ON [PRIMARY]
数据样本:
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (1, 1, N'Toh', 0, 0, N'', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (2, 2, N'Man', 1, 1, N'Child of Toh', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (3, 3, N'Rul', 1, 1, N'Child of Toh', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (4, 4, N'Rafiq', 2, 2, N'Child of Man', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (5, 5, N'Paan', 2, 2, N'Child of Man', NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7857, 6, N'TohChild0', 3, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7858, 7, N'TohChild1', 3, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7859, 8, N'TohChild2', 4, 1, NULL, NULL)
INSERT [dbo].[TblHierarchy] ([ID], [AgentID], [AgentName], [RootID], [IntroducerID], [Description], [HierarchyTree]) VALUES (7860, 9, N'TohChild3', 4, 1, NULL, NULL)
这是此 CTE 查询的当前结果
255>127>63>31>15>7>3>1
254>127>63>31>15>7>3>1
253>126>63>31>15>7>3>1
结果是我想要的,但是这个太笼统了。我如何通过使用 AgentID 作为 参数 来获得这样的结果。因此,结果将只有 return 一行。
编辑
RootID 是父级,AgentID 是子级。我想要一个自下而上的层次结构,意味着特定 AgentID 的所有父级
假设 AgentID = 327 所以,我的预期结果将是 327>163>81>40>20>10>5>2>1
提前致谢!
递归 CTE 有两部分:
- 递归种子。这是联合之上的第一个查询,您可以在其中设置迭代的起点。您的起点是 select 任何
agentid
不是rootid
- 递归项。这是一次又一次被调用的查询,直到连接条件失败,表示该特定分支的递归结束。
因为您只想获得特定 agentid
的结果,而不是 - 任何 agentid
不是 rootid
的结果 - 就像您目前拥有的那样,然后更改 WHERE
该递归种子上的子句:
WITH rCTE
AS (
SELECT AgentID,
RootID,
CAST(AgentID AS NVARCHAR(MAX)) AS PathIDs,
CAST(AgentName AS NVARCHAR(MAX)) AS PathText,
CAST(IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM TblHierarchy r
WHERE AgentID = 327
UNION ALL
SELECT n.AgentID,
n.RootID,
r.PathIDs + '>' + CAST(n.AgentID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '>' + n.AgentName AS PathText,
r.PathCost + CAST(n.IntroducerID AS NVARCHAR(MAX)) AS PathCost
FROM rCTE r
INNER JOIN dbo.TblHierarchy n ON r.RootID = n.AgentID
)
SELECT PathIDs,
PathText,
PathCost
FROM rCTE r
WHERE r.RootID = 0 --IS NULL
作为第二个选项,您还可以将 select 的 SELECT 语句从递归 CTE 更改为 WHERE rootID = 0 AND pathIDs like '327%'