SQL - get all parents/childs?
hopefully someone can help with this. I have recieved a table of data which I need to restructure and build a Denorm table out of. The table structure is as follows
UserID Logon ParentID
2344 Test1 2000
2345 Test2 2000
The issue I have is the ParentID is also a UserID of its own and in the same table.
SELECT * FROM tbl where ParentID=2000 gives the below output
UserID Logon ParentID
2000 Test Team 2500
Again, the ParentID of this is also stored as a UserID..
SELECT * FROM tbl where ParentID=2500 gives the below output
UserID Logon ParentID
2500 Test Division NULL
I want a query that will pull all of these relationships and the logons into one row, with my output looking like the below.
UserID Username Parent1 Parent2 Parent3 Parent4
2344 Test1 Test Team Test Division NULL NULL
2345 Test2 Test Team Test Division NULL NULL
The maximum number of parents a user can have is 4, in this case there is only 2. Can someone help me with the query needed to build this?
Appreciate any help
Thanks
Jess
sql sql-server-2012
add a comment |
hopefully someone can help with this. I have recieved a table of data which I need to restructure and build a Denorm table out of. The table structure is as follows
UserID Logon ParentID
2344 Test1 2000
2345 Test2 2000
The issue I have is the ParentID is also a UserID of its own and in the same table.
SELECT * FROM tbl where ParentID=2000 gives the below output
UserID Logon ParentID
2000 Test Team 2500
Again, the ParentID of this is also stored as a UserID..
SELECT * FROM tbl where ParentID=2500 gives the below output
UserID Logon ParentID
2500 Test Division NULL
I want a query that will pull all of these relationships and the logons into one row, with my output looking like the below.
UserID Username Parent1 Parent2 Parent3 Parent4
2344 Test1 Test Team Test Division NULL NULL
2345 Test2 Test Team Test Division NULL NULL
The maximum number of parents a user can have is 4, in this case there is only 2. Can someone help me with the query needed to build this?
Appreciate any help
Thanks
Jess
sql sql-server-2012
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26
add a comment |
hopefully someone can help with this. I have recieved a table of data which I need to restructure and build a Denorm table out of. The table structure is as follows
UserID Logon ParentID
2344 Test1 2000
2345 Test2 2000
The issue I have is the ParentID is also a UserID of its own and in the same table.
SELECT * FROM tbl where ParentID=2000 gives the below output
UserID Logon ParentID
2000 Test Team 2500
Again, the ParentID of this is also stored as a UserID..
SELECT * FROM tbl where ParentID=2500 gives the below output
UserID Logon ParentID
2500 Test Division NULL
I want a query that will pull all of these relationships and the logons into one row, with my output looking like the below.
UserID Username Parent1 Parent2 Parent3 Parent4
2344 Test1 Test Team Test Division NULL NULL
2345 Test2 Test Team Test Division NULL NULL
The maximum number of parents a user can have is 4, in this case there is only 2. Can someone help me with the query needed to build this?
Appreciate any help
Thanks
Jess
sql sql-server-2012
hopefully someone can help with this. I have recieved a table of data which I need to restructure and build a Denorm table out of. The table structure is as follows
UserID Logon ParentID
2344 Test1 2000
2345 Test2 2000
The issue I have is the ParentID is also a UserID of its own and in the same table.
SELECT * FROM tbl where ParentID=2000 gives the below output
UserID Logon ParentID
2000 Test Team 2500
Again, the ParentID of this is also stored as a UserID..
SELECT * FROM tbl where ParentID=2500 gives the below output
UserID Logon ParentID
2500 Test Division NULL
I want a query that will pull all of these relationships and the logons into one row, with my output looking like the below.
UserID Username Parent1 Parent2 Parent3 Parent4
2344 Test1 Test Team Test Division NULL NULL
2345 Test2 Test Team Test Division NULL NULL
The maximum number of parents a user can have is 4, in this case there is only 2. Can someone help me with the query needed to build this?
Appreciate any help
Thanks
Jess
sql sql-server-2012
sql sql-server-2012
asked Nov 22 '18 at 15:08
Jess8766
667
667
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26
add a comment |
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26
add a comment |
4 Answers
4
active
oldest
votes
You can use basicly LEFT JOIN. If you have static 4 parent it should work. If you have unknown parents you should do dynamic query.
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
EDIT : Additional(to exclude parent users from the list) :
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
add a comment |
select
tb1.UserId as UserId,
tb1.UserName as UserName,
tb2.UserName as Parent1,
tb3.UserName as Parent2,
tb4.UserName as Parent3,
tb5.UserName as Parent4
from tbl t1
left join tbl t2 on t2.UserId=t1.ParentID
left join tbl t3 on t3.UserId=t2.ParentID
left join tbl t4 on t4.UserId=t3.ParentID
left join tbl t5 on t5.UserId=t4.ParentID;
you need to do 4 left joins in order to fetch 4 parent details
add a comment |
Use a recursive CTE to get the levels then pivot to put them in columns:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
See SQL Fiddle example
add a comment |
In order to get all parent or child, it's efficient to use a recursive function which would fetch the whole hierarchy.
Sample Table:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert some values
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
Create recursive function as below
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
If this function is joined with table, it should list the hierarchy for all employees
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
If we do a pivot on the table (excluding the 'Number' column). Assuming we store in the table "#temp" it should list all the managers as a column.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
But this doesn't name the column as 'Parent1', 'Parent2' instead with the dynamic column name.
Link below should help to set custom column name for the dynamic pivot table
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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%2fstackoverflow.com%2fquestions%2f53433788%2fsql-get-all-parents-childs%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use basicly LEFT JOIN. If you have static 4 parent it should work. If you have unknown parents you should do dynamic query.
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
EDIT : Additional(to exclude parent users from the list) :
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
add a comment |
You can use basicly LEFT JOIN. If you have static 4 parent it should work. If you have unknown parents you should do dynamic query.
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
EDIT : Additional(to exclude parent users from the list) :
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
add a comment |
You can use basicly LEFT JOIN. If you have static 4 parent it should work. If you have unknown parents you should do dynamic query.
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
EDIT : Additional(to exclude parent users from the list) :
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
You can use basicly LEFT JOIN. If you have static 4 parent it should work. If you have unknown parents you should do dynamic query.
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
EDIT : Additional(to exclude parent users from the list) :
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
edited Nov 22 '18 at 16:02
answered Nov 22 '18 at 15:23
Zeki Gumus
1,262212
1,262212
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
add a comment |
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
This works but I get some rows where the Username is the parent1. For example I am seeing "Test Team" as a username with Test Division as parent 1. Is there anyway to exclude these?
– Jess8766
Nov 22 '18 at 15:35
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 if you only want rows for users that are not parents you need to add WHERE U1.UserId NOT IN (SELECT ParentId FROM Users)
– Dávid Laczkó
Nov 22 '18 at 15:51
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
@Jess8766 I have added NOT EXISTS condition to the WHERE statement to exclude parent users.
– Zeki Gumus
Nov 22 '18 at 16:04
add a comment |
select
tb1.UserId as UserId,
tb1.UserName as UserName,
tb2.UserName as Parent1,
tb3.UserName as Parent2,
tb4.UserName as Parent3,
tb5.UserName as Parent4
from tbl t1
left join tbl t2 on t2.UserId=t1.ParentID
left join tbl t3 on t3.UserId=t2.ParentID
left join tbl t4 on t4.UserId=t3.ParentID
left join tbl t5 on t5.UserId=t4.ParentID;
you need to do 4 left joins in order to fetch 4 parent details
add a comment |
select
tb1.UserId as UserId,
tb1.UserName as UserName,
tb2.UserName as Parent1,
tb3.UserName as Parent2,
tb4.UserName as Parent3,
tb5.UserName as Parent4
from tbl t1
left join tbl t2 on t2.UserId=t1.ParentID
left join tbl t3 on t3.UserId=t2.ParentID
left join tbl t4 on t4.UserId=t3.ParentID
left join tbl t5 on t5.UserId=t4.ParentID;
you need to do 4 left joins in order to fetch 4 parent details
add a comment |
select
tb1.UserId as UserId,
tb1.UserName as UserName,
tb2.UserName as Parent1,
tb3.UserName as Parent2,
tb4.UserName as Parent3,
tb5.UserName as Parent4
from tbl t1
left join tbl t2 on t2.UserId=t1.ParentID
left join tbl t3 on t3.UserId=t2.ParentID
left join tbl t4 on t4.UserId=t3.ParentID
left join tbl t5 on t5.UserId=t4.ParentID;
you need to do 4 left joins in order to fetch 4 parent details
select
tb1.UserId as UserId,
tb1.UserName as UserName,
tb2.UserName as Parent1,
tb3.UserName as Parent2,
tb4.UserName as Parent3,
tb5.UserName as Parent4
from tbl t1
left join tbl t2 on t2.UserId=t1.ParentID
left join tbl t3 on t3.UserId=t2.ParentID
left join tbl t4 on t4.UserId=t3.ParentID
left join tbl t5 on t5.UserId=t4.ParentID;
you need to do 4 left joins in order to fetch 4 parent details
edited Nov 23 '18 at 3:07
Pawel Czapski
1,2141917
1,2141917
answered Nov 22 '18 at 15:20
nikhilesh soni
111
111
add a comment |
add a comment |
Use a recursive CTE to get the levels then pivot to put them in columns:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
See SQL Fiddle example
add a comment |
Use a recursive CTE to get the levels then pivot to put them in columns:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
See SQL Fiddle example
add a comment |
Use a recursive CTE to get the levels then pivot to put them in columns:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
See SQL Fiddle example
Use a recursive CTE to get the levels then pivot to put them in columns:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
See SQL Fiddle example
edited Nov 23 '18 at 10:20
answered Nov 23 '18 at 10:12
Andy N
411313
411313
add a comment |
add a comment |
In order to get all parent or child, it's efficient to use a recursive function which would fetch the whole hierarchy.
Sample Table:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert some values
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
Create recursive function as below
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
If this function is joined with table, it should list the hierarchy for all employees
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
If we do a pivot on the table (excluding the 'Number' column). Assuming we store in the table "#temp" it should list all the managers as a column.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
But this doesn't name the column as 'Parent1', 'Parent2' instead with the dynamic column name.
Link below should help to set custom column name for the dynamic pivot table
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
add a comment |
In order to get all parent or child, it's efficient to use a recursive function which would fetch the whole hierarchy.
Sample Table:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert some values
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
Create recursive function as below
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
If this function is joined with table, it should list the hierarchy for all employees
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
If we do a pivot on the table (excluding the 'Number' column). Assuming we store in the table "#temp" it should list all the managers as a column.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
But this doesn't name the column as 'Parent1', 'Parent2' instead with the dynamic column name.
Link below should help to set custom column name for the dynamic pivot table
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
add a comment |
In order to get all parent or child, it's efficient to use a recursive function which would fetch the whole hierarchy.
Sample Table:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert some values
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
Create recursive function as below
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
If this function is joined with table, it should list the hierarchy for all employees
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
If we do a pivot on the table (excluding the 'Number' column). Assuming we store in the table "#temp" it should list all the managers as a column.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
But this doesn't name the column as 'Parent1', 'Parent2' instead with the dynamic column name.
Link below should help to set custom column name for the dynamic pivot table
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
In order to get all parent or child, it's efficient to use a recursive function which would fetch the whole hierarchy.
Sample Table:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert some values
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
Create recursive function as below
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
If this function is joined with table, it should list the hierarchy for all employees
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
If we do a pivot on the table (excluding the 'Number' column). Assuming we store in the table "#temp" it should list all the managers as a column.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
But this doesn't name the column as 'Parent1', 'Parent2' instead with the dynamic column name.
Link below should help to set custom column name for the dynamic pivot table
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
edited Nov 23 '18 at 11:18
answered Nov 22 '18 at 18:06
Prem Kumar
214
214
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- 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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2fstackoverflow.com%2fquestions%2f53433788%2fsql-get-all-parents-childs%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
Please show us what you have tried, and why its not working.
– Dave Cullum
Nov 22 '18 at 15:13
One solution I found had the parents and childIDs on separate table which isn't the case here. i wouldn't know where to start with the above as I am not too advanced
– Jess8766
Nov 22 '18 at 15:15
Have a look at recursive cte. An application is in this link: stackoverflow.com/questions/959804/….
– Mischa Vreeburg
Nov 22 '18 at 16:26