Select all children down a hierarchy
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
add a comment |
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
add a comment |
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
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
sql-server sql-server-2005 recursive
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
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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;
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
add a comment |
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;
add a comment |
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;
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;
edited 13 mins ago
David Brossard
1055
1055
answered Aug 21 '16 at 6:07
Liya TanskyLiya Tansky
14414
14414
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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