Reputation: 179
I have hierarchical data with parents and children together with positions.
Sample:
create table groups
(
Child varchar(1),
Parent varchar(1),
Position int
);
insert into groups (Child, Parent, Position)
values ('A', NULL, 1),
('B', 'A', 1),
('C', 'B', 1),
('D', 'B', 2),
('E', NULL, 2),
('F', NULL, 3),
('G', 'F', 1),
('H', 'G', 1),
('I', 'G', 2),
('J', 'F', 2),
('K', 'J', 1),
('L', 'J', 2);
Each group and subgroup has it own position starting with 1, e.g.:
I need to order the query the way that the children of the parents always come between parents ascending, for example (added levels for better imagination):
Level|Child|Parent|Position
-----+-----+------+---------
3 | A | NULL | 1
2 | B | A | 1
1 | C | B | 1
1 | D | B | 2
3 | E | NULL | 2
3 | F | NULL | 3
2 | G | F | 1
1 | H | G | 1
1 | I | G | 2
2 | J | F | 2
1 | K | J | 1
1 | L | J | 2
This is my current code:
;with cte as
(
select Child, Parent, Position
from groups
union all
select t.Child, t.Parent, t.Position
from groups t
join cte on t.Child = cte.Parent
)
select distinct *
from cte
order by Position
Thank you
Upvotes: 0
Views: 165
Reputation: 82474
Your cte is a little messed up. Here's how I would do it:
;with cte as (
select Child, Parent, Position As ParentPosition, Position, 1 As level
from groups
where parent is null
union all
select t.Child, t.Parent, cte.ParentPosition, t.Position, level + 1
from groups AS t
join cte on t.Parent = cte.Child
)
select *
from cte
order by ParentPosition, level, Position
Your cte's anchor part was all the records in the table, where in fact it should be just the records that has no parents (hence the where parent is null
).
Also, I've added a column for the parent's position to enable sorting all the children of the same parent before the next parent, and I've added a level column to help order the children by distance from the main parent.
Results:
Child Parent ParentPosition Position level
A 1 1 1
B A 1 1 2
C B 1 1 3
D B 1 2 3
E 2 2 1
F 3 3 1
G F 3 1 2
J F 3 2 2
K J 3 1 3
H G 3 1 3
I G 3 2 3
L J 3 2 3
Upvotes: 1