[英]Conversion of CTE to temp table in SQL Server to get All Possible Parents
我有一个用户表,在其中维护了父子关系,并且希望生成包含所有用户ID以及其父ID和所有可能的层次父作为逗号分隔字符串的结果。
我的表结构如下。
CREATE TABLE [hybarmoney].[Users](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[USERID] [nvarchar](100) NULL,
[REFERENCEID] [bigint] NULL
)
我正在使用下面的CTE获得结果
;WITH Hierarchy (
ChildId
,ChildName
,ParentId
,Parents
)
AS (
SELECT Id
,USERID
,REFERENCEID
,CAST('' AS VARCHAR(MAX))
FROM hybarmoney.Users AS FirtGeneration
WHERE REFERENCEID = 0
UNION ALL
SELECT NextGeneration.ID
,NextGeneration.UserID
,Parent.ChildId
,CAST(CASE
WHEN Parent.Parents = ''
THEN (CAST(NextGeneration.REFERENCEID AS VARCHAR(MAX)))
ELSE (Parent.Parents + ',' + CAST(NextGeneration.REFERENCEID AS VARCHAR(MAX)))
END AS VARCHAR(MAX))
FROM hybarmoney.Users AS NextGeneration
INNER JOIN Hierarchy AS Parent ON NextGeneration.REFERENCEID = Parent.ChildId
)
SELECT *
FROM Hierarchy
ORDER BY ChildId
OPTION (MAXRECURSION 0)
但是我受到MAXRECURSION的限制,当我用Google搜索时,我知道临时表是一种替代解决方案,但是我却不能做到这一点,而且我也不想让所有可能的顶级父母都成为我的目标希望为每个用户找到15个层次父级。 如果可能的话,是否可以将临时表用于我的目的。
为了仅获得N
个CTE级别,您可以做的是创建一个附加列来跟踪每个级别。
;WITH Hierarchy (
ChildId
,ChildName
,ParentId
,LEVEL
,Parents
)
AS (
SELECT Id
,USERID
,REFERENCEID
,0 AS LEVEL
,CAST('' AS VARCHAR(MAX))
FROM hybarmoney.Users AS FirtGeneration
WHERE REFERENCEID = 0
UNION ALL
SELECT NextGeneration.ID
,NextGeneration.UserID
,Parent.ChildId
,LEVEL+1 AS LEVEL
,CAST(CASE
WHEN Parent.Parents = ''
THEN (CAST(NextGeneration.REFERENCEID AS VARCHAR(MAX)))
ELSE (Parent.Parents + ',' + CAST(NextGeneration.REFERENCEID AS VARCHAR(MAX)))
END AS VARCHAR(MAX))
FROM hybarmoney.Users AS NextGeneration
INNER JOIN Hierarchy AS Parent ON NextGeneration.REFERENCEID = Parent.ChildId
)
SELECT *
FROM Hierarchy
WHERE LEVEL <= 15
ORDER BY ChildId
OPTION (MAXRECURSION 0)
假设我正确理解了您的以下语句,此方法将起作用:“出于我的目的,我想为每个用户找到15个等级的父级”,其中实际上是指单个用户的 15个等级的父级(在您的情况下, REFERENCEID=0
) 。
如果您希望此表为hybarmoney.Users
表中的每个用户生成15个层次父hybarmoney.Users
列表,则将CTE移到表值函数中,并实现此处所述的类似解决方案。
如果可能有更好的解决方案,则使用流动查询得到相同的结果
Create PROC UspUpdateUserAndFiftenLevelIDs (@UserID BIGINT)
AS
BEGIN
DECLARE @REFERENCEIDString NVARCHAR(max)
SET @REFERENCEIDString = ''
DECLARE @ReferenceID BIGINT
SET @ReferenceID = @UserID
DECLARE @Count INT
SET @Count = 0
WHILE (@count < 15)
BEGIN
SELECT @ReferenceID = U.REFERENCEID
,@REFERENCEIDString = @REFERENCEIDString + CASE
WHEN @REFERENCEIDString = ''
THEN (CAST(U.REFERENCEID AS VARCHAR(100)))
ELSE (',' + CAST(U.REFERENCEID AS VARCHAR(MAX)))
END
FROM hybarmoney.Users U
WHERE U.ID = @ReferenceID
SET @Count = @Count + 1
END
SELECT @UserID
,@REFERENCEIDString
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.