Parent child Hierarchy based on non unique order number
I have a table containing system and order number column which is not unique.I would like to connect the system based on the order number
+----------------------+
¦ system ¦OrderNo¦
¦--------------+-------+
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system3 ¦ 3 ¦
¦ system4 ¦ 4 ¦
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system5 ¦ 1 ¦
¦ system6 ¦ 2 ¦
¦ system7 ¦ 1 ¦
¦ system8 ¦ 2 ¦
+----------------------+
How do I generate a parent child relation based on the OrderNo Column. Where 1-2-3-4 are one set, 1-2,1-2,1-2 the other set
desired Output is as below
+----------------------+
¦ Parent ¦Child ¦
¦--------------+-------+
¦ system1 ¦system2¦
¦ system2 ¦system3¦
¦ system3 ¦system4¦
¦ system4 ¦NULL ¦
¦ system1 ¦system2¦
¦ system2 ¦NULL ¦
¦ system5 ¦system6¦
¦ system6 ¦NULL ¦
¦ system7 ¦system8¦
¦ system8 ¦NULL ¦
+----------------------+
sql sql-server sql-server-2008 hierarchy hierarchical-data
add a comment |
I have a table containing system and order number column which is not unique.I would like to connect the system based on the order number
+----------------------+
¦ system ¦OrderNo¦
¦--------------+-------+
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system3 ¦ 3 ¦
¦ system4 ¦ 4 ¦
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system5 ¦ 1 ¦
¦ system6 ¦ 2 ¦
¦ system7 ¦ 1 ¦
¦ system8 ¦ 2 ¦
+----------------------+
How do I generate a parent child relation based on the OrderNo Column. Where 1-2-3-4 are one set, 1-2,1-2,1-2 the other set
desired Output is as below
+----------------------+
¦ Parent ¦Child ¦
¦--------------+-------+
¦ system1 ¦system2¦
¦ system2 ¦system3¦
¦ system3 ¦system4¦
¦ system4 ¦NULL ¦
¦ system1 ¦system2¦
¦ system2 ¦NULL ¦
¦ system5 ¦system6¦
¦ system6 ¦NULL ¦
¦ system7 ¦system8¦
¦ system8 ¦NULL ¦
+----------------------+
sql sql-server sql-server-2008 hierarchy hierarchical-data
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of anORDER BY
clause, and thus you have no way to determine the relationship.
– Larnu
Nov 24 '18 at 21:46
add a comment |
I have a table containing system and order number column which is not unique.I would like to connect the system based on the order number
+----------------------+
¦ system ¦OrderNo¦
¦--------------+-------+
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system3 ¦ 3 ¦
¦ system4 ¦ 4 ¦
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system5 ¦ 1 ¦
¦ system6 ¦ 2 ¦
¦ system7 ¦ 1 ¦
¦ system8 ¦ 2 ¦
+----------------------+
How do I generate a parent child relation based on the OrderNo Column. Where 1-2-3-4 are one set, 1-2,1-2,1-2 the other set
desired Output is as below
+----------------------+
¦ Parent ¦Child ¦
¦--------------+-------+
¦ system1 ¦system2¦
¦ system2 ¦system3¦
¦ system3 ¦system4¦
¦ system4 ¦NULL ¦
¦ system1 ¦system2¦
¦ system2 ¦NULL ¦
¦ system5 ¦system6¦
¦ system6 ¦NULL ¦
¦ system7 ¦system8¦
¦ system8 ¦NULL ¦
+----------------------+
sql sql-server sql-server-2008 hierarchy hierarchical-data
I have a table containing system and order number column which is not unique.I would like to connect the system based on the order number
+----------------------+
¦ system ¦OrderNo¦
¦--------------+-------+
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system3 ¦ 3 ¦
¦ system4 ¦ 4 ¦
¦ system1 ¦ 1 ¦
¦ system2 ¦ 2 ¦
¦ system5 ¦ 1 ¦
¦ system6 ¦ 2 ¦
¦ system7 ¦ 1 ¦
¦ system8 ¦ 2 ¦
+----------------------+
How do I generate a parent child relation based on the OrderNo Column. Where 1-2-3-4 are one set, 1-2,1-2,1-2 the other set
desired Output is as below
+----------------------+
¦ Parent ¦Child ¦
¦--------------+-------+
¦ system1 ¦system2¦
¦ system2 ¦system3¦
¦ system3 ¦system4¦
¦ system4 ¦NULL ¦
¦ system1 ¦system2¦
¦ system2 ¦NULL ¦
¦ system5 ¦system6¦
¦ system6 ¦NULL ¦
¦ system7 ¦system8¦
¦ system8 ¦NULL ¦
+----------------------+
sql sql-server sql-server-2008 hierarchy hierarchical-data
sql sql-server sql-server-2008 hierarchy hierarchical-data
asked Nov 24 '18 at 21:43
xoanonxoanon
1009
1009
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of anORDER BY
clause, and thus you have no way to determine the relationship.
– Larnu
Nov 24 '18 at 21:46
add a comment |
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of anORDER BY
clause, and thus you have no way to determine the relationship.
– Larnu
Nov 24 '18 at 21:46
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of an
ORDER BY
clause, and thus you have no way to determine the relationship.– Larnu
Nov 24 '18 at 21:46
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of an
ORDER BY
clause, and thus you have no way to determine the relationship.– Larnu
Nov 24 '18 at 21:46
add a comment |
1 Answer
1
active
oldest
votes
As I mentioned in my comment, if these are the only columns you have, what you are after isn't achievable. Without some kind of a ascending unique key, you have no way of determining the relationship. If we do add a unique ascending key then we can achieve this.
If you were using SQL Server 2012+ (2008 is out of support, and very close to end of extended support, so upgrading should be a very high priority right now), then you could generate your islands using ROWS BETWEEN
and then use LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Without access to LEAD
and ROWS BETWEEN
you'll have to be more creative; and the solution is going to be far slower:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
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%2f53462622%2fparent-child-hierarchy-based-on-non-unique-order-number%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
As I mentioned in my comment, if these are the only columns you have, what you are after isn't achievable. Without some kind of a ascending unique key, you have no way of determining the relationship. If we do add a unique ascending key then we can achieve this.
If you were using SQL Server 2012+ (2008 is out of support, and very close to end of extended support, so upgrading should be a very high priority right now), then you could generate your islands using ROWS BETWEEN
and then use LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Without access to LEAD
and ROWS BETWEEN
you'll have to be more creative; and the solution is going to be far slower:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
add a comment |
As I mentioned in my comment, if these are the only columns you have, what you are after isn't achievable. Without some kind of a ascending unique key, you have no way of determining the relationship. If we do add a unique ascending key then we can achieve this.
If you were using SQL Server 2012+ (2008 is out of support, and very close to end of extended support, so upgrading should be a very high priority right now), then you could generate your islands using ROWS BETWEEN
and then use LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Without access to LEAD
and ROWS BETWEEN
you'll have to be more creative; and the solution is going to be far slower:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
add a comment |
As I mentioned in my comment, if these are the only columns you have, what you are after isn't achievable. Without some kind of a ascending unique key, you have no way of determining the relationship. If we do add a unique ascending key then we can achieve this.
If you were using SQL Server 2012+ (2008 is out of support, and very close to end of extended support, so upgrading should be a very high priority right now), then you could generate your islands using ROWS BETWEEN
and then use LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Without access to LEAD
and ROWS BETWEEN
you'll have to be more creative; and the solution is going to be far slower:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;
As I mentioned in my comment, if these are the only columns you have, what you are after isn't achievable. Without some kind of a ascending unique key, you have no way of determining the relationship. If we do add a unique ascending key then we can achieve this.
If you were using SQL Server 2012+ (2008 is out of support, and very close to end of extended support, so upgrading should be a very high priority right now), then you could generate your islands using ROWS BETWEEN
and then use LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Without access to LEAD
and ROWS BETWEEN
you'll have to be more creative; and the solution is going to be far slower:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;
edited Nov 24 '18 at 22:10
answered Nov 24 '18 at 22:03
LarnuLarnu
20.2k51732
20.2k51732
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
add a comment |
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
It works great on sql server 2008, but without LEAD the output is not the same
– xoanon
Nov 28 '18 at 12:40
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.
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%2f53462622%2fparent-child-hierarchy-based-on-non-unique-order-number%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
Are those the only columns you have? If so, impossible with that data; you cannot guarantee the order of your data with the use of an
ORDER BY
clause, and thus you have no way to determine the relationship.– Larnu
Nov 24 '18 at 21:46