I have a problem that I’m trying to solve that I think is different from other SQL adjacency list hierarchy problems I’ve researched here. I’m trying to sort the data such that all children are listed before any of their parents. I already have CTE’s that return all the children of a given ParentID and all the parents of a given ChildID, but those don’t fit my current need.
I have two tables:
CREATE TABLE [dbo].[ItemMaster](
[ItemID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CREATE TABLE [dbo].[References](
[RefID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NOT NULL,
[ChildID] [int] NOT NULL,
Foreign key relationships exist between ItemMaster.ItemID to References.ParentID and References.ChildID
Here’s some example data from my tables…
ItemID, Name
- 1, A1
- 2, A2
- 3, A3
- 4, P1
- 5, P2
- 6, P3
- 7, P4
- 8, TOP
RefID, ParentID, ChildID
- 1,1,5
- 2,2,5
- 3,2,6
- 4,3,2
- 5,7,3
- 6,8,4
- 7,8,1
- 8,8,2
- 9,8,3
- 10,8,7
The output I want would list each ItemID and Name with the children listed before any parents. Like this…
ItemID, Name
- 4, P1
- 5, P2
- 6, P3
- 1, A1
- 2, A2
- 3, A3
- 7, P4
- 8, Top
Notes:
- Any ItemID can have 0, 1 or > 1 parents.
- Those that don’t have any parents would be listed at the top of the output.
- I don’t have NULL values for the “top most parents” in the reference table.
I hope I’ve given enough detail and explained myself well enough to get some feedback. Any ideas would be greatly appreciated!
I think the way to achieve this is using a recursive operation and assigning a weight to each node, based on the weight of all its children.
For example any leaf in this tree will have a weight of zero since it doesn’t have any children. Its immediate parent will be 1, and the parent’s parent 2 and so on. Sorting on the weight should return the result set you need. Here is the recursive function I used to test my theory:
This returns the result set you posted:
Best of luck 🙂