TSQL递归查询帮助父-子
我正在尝试构建一个t-sql查询,该查询将基于汇总输入返回同一表中的父帐户及其子帐户。有人能帮忙吗TSQL递归查询帮助父-子,tsql,recursion,parent-child,recursive-query,Tsql,Recursion,Parent Child,Recursive Query,我正在尝试构建一个t-sql查询,该查询将基于汇总输入返回同一表中的父帐户及其子帐户。有人能帮忙吗 ***TABLE:USERS*** UserId ParentId 66 -1 67 -1 68 -1 69 54 70 55 71 56 72 57 这是到目前为止我所拥有的,但它只返回一个帐户,这是最后一个帐户,我需要在递归中包含ParentId,这样它将一个接一个地提取父帐户和子帐户的列表
***TABLE:USERS***
UserId ParentId
66 -1
67 -1
68 -1
69 54
70 55
71 56
72 57
这是到目前为止我所拥有的,但它只返回一个帐户,这是最后一个帐户,我需要在递归中包含ParentId,这样它将一个接一个地提取父帐户和子帐户的列表
DECLARE @RollUp AS bit
DECLARE @ParentID As INT
SELECT @RollUp = 0
If @Rollup = 1 SELECT @ParentID = CASE WHEN ParentID = -1
THEN Users.USER_ID
Else ParentID END
FROM Users WHERE user_Id IN (70,71) ELSE
SELECT @ParentID = Users.USER_ID
FROM Users WHERE USER_Id IN (70,71) ;
WITH TRAVERSE_TREE_CTE AS
(
Select User_ID,ParentID
FROM Users
WHERE User_ID = @ParentID
UNION ALL Select Users.User_ID, Users.ParentID
FROM TRAVERSE_TREE_CTE INNER
JOIN Users
ON TRAVERSE_TREE_CTE.User_ID = Users.ParentID
)
Select * from Users
where User_id IN (SELECT distinct User_ID FROM TRAVERSE_TREE_CTE)
我认为递归中引用的是绝对值
Where User_ID = @ParentID
通常在递归部分之后执行谓词,而不是在递归过程中。有时可能会出现这种情况,但递归表达式中的绝对值通常会给出不可预测的结果,因为您试图在一个实例上将显式连接到其父级。但是,您通常还需要告诉表达式您要查找的递归级别以及确定该级别后的谓词
下面是一个自我填充的示例,可能会有所帮助。它将查找最大递归级别并仅确定该级别
Declare @table table ( PersonId int identity, PersonName varchar(512), Account int, ParentId int, Orders int);
insert into @Table values ('Brett', 1, NULL, 1000),('John', 1, 1, 100),('James', 1, 1, 200),('Beth', 1, 2, 300),('John2', 2, 4, 400);
select
PersonID
, PersonName
, Account
, ParentID
from @Table
; with recursion as
(
select
t1.PersonID
, t1.PersonName
, t1.Account
--, t1.ParentID
, cast(isnull(t2.PersonName, '')
+ Case when t2.PersonName is not null then '\' + t1.PersonName else t1.PersonName end
as varchar(255)) as fullheirarchy
, 1 as pos
, cast(t1.orders +
isnull(t2.orders,0) -- if the parent has no orders than zero
as int) as Orders
from @Table t1
left join @Table t2 on t1.ParentId = t2.PersonId
union all
select
t.PersonID
, t.PersonName
, t.Account
--, t.ParentID
, cast(r.fullheirarchy + '\' + t.PersonName as varchar(255))
, pos + 1 -- increases
, r.orders + t.orders
from @Table t
join recursion r on t.ParentId = r.PersonId
)
, b as
(
select *, max(pos) over(partition by PersonID) as maxrec -- I find the maximum occurrence of position by person
from recursion
)
select *
from b
where pos = maxrec -- finds the furthest down tree
-- and Account = 2 -- I could find just someone from a different department
已更新
如果您只想查看与变量ID相关的子元素,则可以将表连接回自身,而无需使用递归
Declare @table table ( PersonId int identity, PersonName varchar(512), Account int, ParentId int, Orders int);
insert into @Table values ('Brett', 1, NULL, 1000),('John', 1, 1, 100),('James', 1, 1, 200),('Beth', 1, 2, 300),('John2', 2, 4, 400);
declare @Id int = 1 -- set to 1, 2, 3, 4, 5
select
a.PersonName
, isnull(b.PersonName,'No Child') as [ChildName(s)]
from @table a
left join @table b on a.Personid = b.ParentId
where a.PersonId = @Id
我只需要WHERE子句中所选用户ID及其各自子关联的结果,而不是所有结果。那没用。除非你有一个不断变化的继承权结构,否则你不需要使用递归。如果只想找到子元素,只需将其连接回自身即可。从对象a连接到对象b上的a.id=b.parentid。b、 (columnname)现在与子元素相关,子元素可以是一个或多个。请参阅updated。我想为几个需要WHERE user\u id IN()子句的user\u id查找父元素和子元素。如何遍历这些用户ID,找到子元素并选择它们?只要ParentID和ID匹配,就可以有多个集合具有相同的父元素,反之亦然。如果级别只有一个深度,则可以执行更新的示例。递归通常在您不知道某个级别向下走了多远,或者某个级别比其他级别长或短时执行。如果您有一个表,其中有20个成员具有父级a,15个成员具有父级B,那么更新后的表应该可以工作。