1

thanks in advance for you help. I'm still quite new to MS SQL db but I was wondering why my recursive query for MSSQL below does not return the value i'm expecting. I've done my research and at the bottom is the code I came up with. Lets say I have the following table...

CategoryID    ParentID    SomeName
1             0           hmm
2             0           err
3             0           woo
4             3           ppp
5             4           ttt

I'm expecting the query below to return 3 4 5. I basically wanted to get the list of category id's heirarchy below it self inclusive based on the category id I pass in the recursive query. Thanks for you assistance.

GO
WITH RecursiveQuery (CategoryID)
AS
(
-- Anchor member definition
    SELECT a.CategoryID 
    FROM [SomeDB].[dbo].[SomeTable] AS a
    WHERE a.ParentID = CategoryID 
    UNION ALL
-- Recursive member definition
    SELECT b.CategoryID
    FROM [SomeDB].[dbo].[SomeTable] AS b
    INNER JOIN RecursiveQuery AS d
        ON d.CategoryID = b.ParentID
)
-- Statement that executes the CTE
SELECT o.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS o
INNER JOIN RecursiveQuery AS d
    ON d.CategoryID = 3
GO
4
  • WHERE a.ParentID = 0, WHERE b.ParentID = d.theID Commented Jul 8, 2016 at 9:26
  • And I guess final select might be from RecursiveQuery. d.theID will not produce crosscutting value 3 it will be the list of all ids. So filter = 3 will give you one record. Commented Jul 8, 2016 at 9:27
  • As @IvanStarostin says, your anchor member definition isn't anchoring to a record. The anchor should be one record that acts as your starting point. Commented Jul 8, 2016 at 9:27
  • ok thanks I thought anchor was the terminating condition ok my mistake will try it out... Commented Jul 8, 2016 at 9:34

2 Answers 2

3

If you want tree from specific root:

DECLARE @rootCatID int = 3

;WITH LessonsTree (CatID)
AS
(
    SELECT a.CategoryID
    FROM [EducationDatabase].[dbo].[LessonCategory] AS a
    WHERE a.CategoryID = @rootCatID ---<<<

    UNION ALL

    SELECT b.CategoryID
    FROM LessonsTree as t
    INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS b
        ON b.ParentID = t.CatID
)
SELECT o.*
FROM LessonsTree t
INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS o
    ON o.CategoryID = t.CatID
Sign up to request clarification or add additional context in comments.

2 Comments

@debonaire you should mark it as the answer if it is.
thanks will do now. can you approve the edit of the variable name thanks so much
1

As stated in the comments, the anchor isn't restricted. Easiest solution is to add the criterium in the anchor

with RecursiveQuery (theID)
AS
(
    SELECT a.ParentID --root id=parentid to include it and to prevent an extra trip to LessonCategory afterwards
    FROM  [LessonCategory] AS a
    WHERE a.ParentID = 3 --restriction here
    UNION ALL
    SELECT b.CategoryID
    FROM [LessonCategory] AS b
    INNER JOIN RecursiveQuery AS d
        ON d.theID = b.ParentID
)
SELECT* from RecursiveQuery

Another option is to have the recursive query be general (no restricted anchor) and have it keep the rootid as well. Then the query on the cte can restrict on the rootid (the first option is probably better, this second one is mainly suitable if you are created some sort of root-view)

with RecursiveQuery 
AS
(
    SELECT a.ParentID theID, a.ParentID RootID
    FROM  [LessonCategory] AS a    
    UNION ALL
    SELECT b.CategoryID, d.RootID
    FROM [LessonCategory] AS b
    INNER JOIN RecursiveQuery AS d
        ON d.theID = b.ParentID
)
SELECT theID from RecursiveQuery where RootID = 3

1 Comment

thanks so much for the suggestions. Will take that into account. Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.