Select products where the category belongs to any category in the hierarchy

前端 未结 9 1652
再見小時候
再見小時候 2021-02-06 05:39

I have a products table that contains a FK for a category, the Categories table is created in a way that each category can have a parent category, example:

Compu         


        
9条回答
  •  北恋
    北恋 (楼主)
    2021-02-06 06:15

    i like to use a stack temp table for hierarchal data. here's a rough example -

    -- create a categories table and fill it with 10 rows (with random parentIds)
    CREATE TABLE Categories ( Id uniqueidentifier, ParentId uniqueidentifier )
    GO
    
    INSERT
    INTO   Categories
    SELECT NEWID(),
           NULL 
    GO
    
    INSERT
    INTO   Categories
    SELECT   TOP(1)NEWID(),
             Id
    FROM     Categories
    ORDER BY Id
    GO 9
    
    
    DECLARE  @lvl INT,            -- holds onto the level as we move throught the hierarchy
             @Id Uniqueidentifier -- the id of the current item in the stack
    
    SET @lvl = 1
    
    CREATE TABLE #stack (item UNIQUEIDENTIFIER, [lvl] INT)
    -- we fill fill this table with the ids we want
    CREATE TABLE #tmpCategories (Id UNIQUEIDENTIFIER)
    
    -- for this example we’ll just select all the ids 
    -- if we want all the children of a specific parent we would include it’s id in
    -- this where clause
    INSERT INTO #stack SELECT Id, @lvl FROM Categories WHERE ParentId IS NULL
    
    WHILE @lvl > 0
    BEGIN -- begin 1
    
          IF EXISTS ( SELECT * FROM #stack WHERE lvl = @lvl )
          BEGIN -- begin 2
    
          SELECT @Id = [item]
          FROM #stack
          WHERE lvl = @lvl
    
          INSERT INTO #tmpCategories
          SELECT @Id
    
          DELETE FROM #stack
          WHERE lvl = @lvl
          AND item = @Id
    
          INSERT INTO #stack
          SELECT Id, @lvl + 1
          FROM   Categories
          WHERE  ParentId = @Id
    
          IF @@ROWCOUNT > 0
          BEGIN -- begin 3
             SELECT @lvl = @lvl + 1
          END -- end 3
       END -- end 2
       ELSE
       SELECT @lvl = @lvl - 1
    
    END -- end 1
    
    DROP TABLE #stack
    
    SELECT * FROM #tmpCategories
    DROP TABLE #tmpCategories
    DROP TABLE Categories
    

    there is a good explanation here link text

提交回复
热议问题