繁体   English   中英

将CTE转换为SQL Server中的临时表以获取所有可能的父级

[英]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)

从CTE以上获得的结果

但是我受到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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM