Select all children down a hierarchy












0















I have a table of hierarchical data like this:



BookGroupID  GroupName  ParentGroupID
----------- --------- -------------
0 Primary 0
1 abc 0
2 abd 0
3 abe 0
4 cbc 1
5 ceg 2
6 cjd 3
7 hjd 5
8 bjy 5
9 mfs 4
10 ikl 7
11 hjy 8
12 mnf 5
13 aws 10
14 qws 11
15 aqe 13


I want to select a specific BookGroupID and all its direct and indirect children down the hierarchy. For instance, for the BookGroupID of 2 the output should look like this:



BookGroupID
-----------
2
5
7
8
10
11
12
13
14
15


To explain, row 5 is in the output because it is a direct child of row 2, rows 7, 8 and 12 are direct children of 5, 15 is a child of 13 which is a child of 10 which is a child of 7, 14 is a child of 11 which is a child of 8.



So, how can I do that in SQL?










share|improve this question





























    0















    I have a table of hierarchical data like this:



    BookGroupID  GroupName  ParentGroupID
    ----------- --------- -------------
    0 Primary 0
    1 abc 0
    2 abd 0
    3 abe 0
    4 cbc 1
    5 ceg 2
    6 cjd 3
    7 hjd 5
    8 bjy 5
    9 mfs 4
    10 ikl 7
    11 hjy 8
    12 mnf 5
    13 aws 10
    14 qws 11
    15 aqe 13


    I want to select a specific BookGroupID and all its direct and indirect children down the hierarchy. For instance, for the BookGroupID of 2 the output should look like this:



    BookGroupID
    -----------
    2
    5
    7
    8
    10
    11
    12
    13
    14
    15


    To explain, row 5 is in the output because it is a direct child of row 2, rows 7, 8 and 12 are direct children of 5, 15 is a child of 13 which is a child of 10 which is a child of 7, 14 is a child of 11 which is a child of 8.



    So, how can I do that in SQL?










    share|improve this question



























      0












      0








      0


      1






      I have a table of hierarchical data like this:



      BookGroupID  GroupName  ParentGroupID
      ----------- --------- -------------
      0 Primary 0
      1 abc 0
      2 abd 0
      3 abe 0
      4 cbc 1
      5 ceg 2
      6 cjd 3
      7 hjd 5
      8 bjy 5
      9 mfs 4
      10 ikl 7
      11 hjy 8
      12 mnf 5
      13 aws 10
      14 qws 11
      15 aqe 13


      I want to select a specific BookGroupID and all its direct and indirect children down the hierarchy. For instance, for the BookGroupID of 2 the output should look like this:



      BookGroupID
      -----------
      2
      5
      7
      8
      10
      11
      12
      13
      14
      15


      To explain, row 5 is in the output because it is a direct child of row 2, rows 7, 8 and 12 are direct children of 5, 15 is a child of 13 which is a child of 10 which is a child of 7, 14 is a child of 11 which is a child of 8.



      So, how can I do that in SQL?










      share|improve this question
















      I have a table of hierarchical data like this:



      BookGroupID  GroupName  ParentGroupID
      ----------- --------- -------------
      0 Primary 0
      1 abc 0
      2 abd 0
      3 abe 0
      4 cbc 1
      5 ceg 2
      6 cjd 3
      7 hjd 5
      8 bjy 5
      9 mfs 4
      10 ikl 7
      11 hjy 8
      12 mnf 5
      13 aws 10
      14 qws 11
      15 aqe 13


      I want to select a specific BookGroupID and all its direct and indirect children down the hierarchy. For instance, for the BookGroupID of 2 the output should look like this:



      BookGroupID
      -----------
      2
      5
      7
      8
      10
      11
      12
      13
      14
      15


      To explain, row 5 is in the output because it is a direct child of row 2, rows 7, 8 and 12 are direct children of 5, 15 is a child of 13 which is a child of 10 which is a child of 7, 14 is a child of 11 which is a child of 8.



      So, how can I do that in SQL?







      sql-server sql-server-2005 recursive






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 20 '16 at 20:57









      Andriy M

      16.3k63473




      16.3k63473










      asked Aug 20 '16 at 6:01









      Riyas VemmullyRiyas Vemmully

      612




      612






















          1 Answer
          1






          active

          oldest

          votes


















          2














          The technique to use is called a recursive common table expression, or recursive CTE. The Microsoft SQL documentation is comprehensive and there are a lot of third-party blog posts to help explain.



          Here's an implementation for your specific question.



          This part just creates the sample data from your question. It uses a temporary table (one that uses the # symbol)



              create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
          insert into #t
          values
          (0 ,'Primary', 0 ),
          (1 ,'abc', 0 ),
          (2 ,'abd', 0 ),
          (3 ,'abe', 0 ),
          (4 ,'cbc', 1 ),
          (5 ,'ceg', 2 ),
          (6 ,'cjd', 3 ),
          (7 ,'hjd', 5 ),
          (8 ,'bjy', 5 ),
          (9 ,'mfs', 4 ),
          (10 ,'ikl', 7 ),
          (11 ,'hjy', 8 ),
          (12 ,'mnf', 5 ),
          (13 ,'aws', 10),
          (14 ,'qws', 11),
          (15 ,'aqe', 13);


          This is the value from which to start looking:



              declare @parent int = 2;


          This is the recursive CTE. You do not have to call it "cte" as in this example. The initial semicolon is redundant. It ensures the previous statement is properly ended if the programmer has been lazy. It does no harm to leave it.



              ;with cte 
          as (select BookGroupId
          from #t as t
          where BookGroupId = @parent
          UNION ALL
          select t.BookGroupId
          from #t as t
          join cte
          on t.ParentGroupId = cte.BookGroupId)
          select *
          from cte
          order by BookGroupId;





          share|improve this answer


























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "182"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f147375%2fselect-all-children-down-a-hierarchy%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            The technique to use is called a recursive common table expression, or recursive CTE. The Microsoft SQL documentation is comprehensive and there are a lot of third-party blog posts to help explain.



            Here's an implementation for your specific question.



            This part just creates the sample data from your question. It uses a temporary table (one that uses the # symbol)



                create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
            insert into #t
            values
            (0 ,'Primary', 0 ),
            (1 ,'abc', 0 ),
            (2 ,'abd', 0 ),
            (3 ,'abe', 0 ),
            (4 ,'cbc', 1 ),
            (5 ,'ceg', 2 ),
            (6 ,'cjd', 3 ),
            (7 ,'hjd', 5 ),
            (8 ,'bjy', 5 ),
            (9 ,'mfs', 4 ),
            (10 ,'ikl', 7 ),
            (11 ,'hjy', 8 ),
            (12 ,'mnf', 5 ),
            (13 ,'aws', 10),
            (14 ,'qws', 11),
            (15 ,'aqe', 13);


            This is the value from which to start looking:



                declare @parent int = 2;


            This is the recursive CTE. You do not have to call it "cte" as in this example. The initial semicolon is redundant. It ensures the previous statement is properly ended if the programmer has been lazy. It does no harm to leave it.



                ;with cte 
            as (select BookGroupId
            from #t as t
            where BookGroupId = @parent
            UNION ALL
            select t.BookGroupId
            from #t as t
            join cte
            on t.ParentGroupId = cte.BookGroupId)
            select *
            from cte
            order by BookGroupId;





            share|improve this answer






























              2














              The technique to use is called a recursive common table expression, or recursive CTE. The Microsoft SQL documentation is comprehensive and there are a lot of third-party blog posts to help explain.



              Here's an implementation for your specific question.



              This part just creates the sample data from your question. It uses a temporary table (one that uses the # symbol)



                  create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
              insert into #t
              values
              (0 ,'Primary', 0 ),
              (1 ,'abc', 0 ),
              (2 ,'abd', 0 ),
              (3 ,'abe', 0 ),
              (4 ,'cbc', 1 ),
              (5 ,'ceg', 2 ),
              (6 ,'cjd', 3 ),
              (7 ,'hjd', 5 ),
              (8 ,'bjy', 5 ),
              (9 ,'mfs', 4 ),
              (10 ,'ikl', 7 ),
              (11 ,'hjy', 8 ),
              (12 ,'mnf', 5 ),
              (13 ,'aws', 10),
              (14 ,'qws', 11),
              (15 ,'aqe', 13);


              This is the value from which to start looking:



                  declare @parent int = 2;


              This is the recursive CTE. You do not have to call it "cte" as in this example. The initial semicolon is redundant. It ensures the previous statement is properly ended if the programmer has been lazy. It does no harm to leave it.



                  ;with cte 
              as (select BookGroupId
              from #t as t
              where BookGroupId = @parent
              UNION ALL
              select t.BookGroupId
              from #t as t
              join cte
              on t.ParentGroupId = cte.BookGroupId)
              select *
              from cte
              order by BookGroupId;





              share|improve this answer




























                2












                2








                2







                The technique to use is called a recursive common table expression, or recursive CTE. The Microsoft SQL documentation is comprehensive and there are a lot of third-party blog posts to help explain.



                Here's an implementation for your specific question.



                This part just creates the sample data from your question. It uses a temporary table (one that uses the # symbol)



                    create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
                insert into #t
                values
                (0 ,'Primary', 0 ),
                (1 ,'abc', 0 ),
                (2 ,'abd', 0 ),
                (3 ,'abe', 0 ),
                (4 ,'cbc', 1 ),
                (5 ,'ceg', 2 ),
                (6 ,'cjd', 3 ),
                (7 ,'hjd', 5 ),
                (8 ,'bjy', 5 ),
                (9 ,'mfs', 4 ),
                (10 ,'ikl', 7 ),
                (11 ,'hjy', 8 ),
                (12 ,'mnf', 5 ),
                (13 ,'aws', 10),
                (14 ,'qws', 11),
                (15 ,'aqe', 13);


                This is the value from which to start looking:



                    declare @parent int = 2;


                This is the recursive CTE. You do not have to call it "cte" as in this example. The initial semicolon is redundant. It ensures the previous statement is properly ended if the programmer has been lazy. It does no harm to leave it.



                    ;with cte 
                as (select BookGroupId
                from #t as t
                where BookGroupId = @parent
                UNION ALL
                select t.BookGroupId
                from #t as t
                join cte
                on t.ParentGroupId = cte.BookGroupId)
                select *
                from cte
                order by BookGroupId;





                share|improve this answer















                The technique to use is called a recursive common table expression, or recursive CTE. The Microsoft SQL documentation is comprehensive and there are a lot of third-party blog posts to help explain.



                Here's an implementation for your specific question.



                This part just creates the sample data from your question. It uses a temporary table (one that uses the # symbol)



                    create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
                insert into #t
                values
                (0 ,'Primary', 0 ),
                (1 ,'abc', 0 ),
                (2 ,'abd', 0 ),
                (3 ,'abe', 0 ),
                (4 ,'cbc', 1 ),
                (5 ,'ceg', 2 ),
                (6 ,'cjd', 3 ),
                (7 ,'hjd', 5 ),
                (8 ,'bjy', 5 ),
                (9 ,'mfs', 4 ),
                (10 ,'ikl', 7 ),
                (11 ,'hjy', 8 ),
                (12 ,'mnf', 5 ),
                (13 ,'aws', 10),
                (14 ,'qws', 11),
                (15 ,'aqe', 13);


                This is the value from which to start looking:



                    declare @parent int = 2;


                This is the recursive CTE. You do not have to call it "cte" as in this example. The initial semicolon is redundant. It ensures the previous statement is properly ended if the programmer has been lazy. It does no harm to leave it.



                    ;with cte 
                as (select BookGroupId
                from #t as t
                where BookGroupId = @parent
                UNION ALL
                select t.BookGroupId
                from #t as t
                join cte
                on t.ParentGroupId = cte.BookGroupId)
                select *
                from cte
                order by BookGroupId;






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 13 mins ago









                David Brossard

                1055




                1055










                answered Aug 21 '16 at 6:07









                Liya TanskyLiya Tansky

                14414




                14414






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Database Administrators Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f147375%2fselect-all-children-down-a-hierarchy%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Liste der Baudenkmale in Friedland (Mecklenburg)

                    Single-Malt-Whisky

                    Czorneboh