Recursive sum in tree structure

后端 未结 5 2022
走了就别回头了
走了就别回头了 2020-12-01 03:05

I have a tree struture in a single table. The table is a tree of categories that can be nested endlessly. Each category has a ProductCount column that tells how many product

5条回答
  •  被撕碎了的回忆
    2020-12-01 03:42

    I couldn't come up with a good T-SQL, set based answer, but I did come up with an answer: The temp table mimics your table structure. The table variable is a work table.

    --Initial table
    CREATE TABLE #products (Id INT, ParentId INT, NAME VARCHAR(255), ProductCount INT)
    INSERT INTO #products
            ( ID,ParentId, NAME, ProductCount )
    VALUES  ( 1,-1,'Cars',0),(2,-1,'Bikes',1),(3,1,'Ford',10),(4,3,'Mustang',7),(5,3,'Focus',4)
    
    --Work table
    DECLARE @products TABLE (ID INT, ParentId INT, NAME VARCHAR(255), ProductCount INT, ProductCountIncludingChildren INT)
    INSERT INTO @products
            ( ID ,
              ParentId ,
              NAME ,
              ProductCount ,
              ProductCountIncludingChildren
            )
    SELECT  Id ,
            ParentId ,
            NAME ,
            ProductCount,
            0
    FROM #products
    
    DECLARE @i INT
    SELECT @i = MAX(id) FROM @products
    
    --Stupid loop - loops suck
    WHILE @i > 0
        BEGIN
            WITH cte AS (SELECT ParentId, SUM(ProductCountIncludingChildren) AS ProductCountIncludingChildren FROM @products GROUP BY ParentId)
            UPDATE p1
            SET p1.ProductCountIncludingChildren = p1.ProductCount + isnull(p2.ProductCountIncludingChildren,0)
            FROM @products p1
            LEFT OUTER JOIN cte p2 ON p1.ID = p2.ParentId
            WHERE p1.ID = @i
    
            SELECT @i = @i - 1
        END
    
    SELECT *
    FROM @products
    
    DROP TABLE #products
    

    I'd be very interested to see a better, set based approach. The problem I ran into is that when you use recursive cte's, you start with the parent and work toward the children - this doesn't really work for getting a sum at the parent levels. You'd have to do some kind of backward recursive cte.

提交回复
热议问题