So I have a set of tables along the lines of the following
cables:
id (integer) | name (char)
knots:
id (integer) | name (char)
cableKnotAttachments:
id (integer) | sourceCableId (integer) | targetKnotId (integer)
cableCableAttachments:
id (integer) | sourceCableId (integer) | targetCableId (integer)
Where a Cable
can be attached to multiple other Cable
s, and multiple Knot
s, and a Knot
can be attached to multiple Cable
s.
Given some Cables.Id
, I need to find all the Knots
which are within that Cable
's children. We say a knot is a child of a Cable
if it is either directly attached, or it is a child of any Cable
which is attached to the Cable
.
My attempt thus far is as follows:
SELECT cableKnotAttachments.targetKnotId
FROM cableKnotAttachments
WHERE cableKnotAttachments.sourceCableId = 1
UNION
SELECT cableKnotAttachments.targetKnotId
FROM cableKnotAttachments
INNER JOIN cableCableAttachments
ON cableKnotAttachments.sourceCableId = cableCableAttachments.targetCableId
WHERE cableCableAttachments.sourceCableId = 1;
In pseudo-code what would be nice:
getDirectlyAttachedKnots(cableId) {
return knots directly attached to cableId
}
getDirectlyAttachedCables(cableId) {
return cables directly attached to cableId
}
getAllChildKnots(cableId) {
knots = getDirectlyAttachedKnots(cableId)
for attachedCableId in getDirectlyAttachedCables(cableId) {
knots += getAllChildKnots(attachedCableId)
}
return knots;
}
But this only covers a single level of recursion (without me just repeating that ad nauseam).
Is there a neat way to do this in SQL Server. It can be assumed that it is not practical to check all Knot
s in a sort of inverse check to this.
Edit:
Adding some sample data for prosperity. Assuming we have Cables
with id
s {1, 2, ..., 4}
; and Knots
with id
s {1, 2, ..., 9}
:
cableCableAttachments:
id | sourceCableId | targetCableId
1 | 1 | 2
2 | 3 | 2
3 | 2 | 4
cableKnotAttachments:
id | sourceCableId | targetKnotId
1 | 1 | 2
2 | 1 | 3
3 | 2 | 4
4 | 3 | 5
5 | 3 | 6
6 | 3 | 7
7 | 4 | 1
8 | 4 | 2
9 | 4 | 3
In which context we would have:
cableId | childKnots
1 | 2, 3, 4, 1
2 | 4, 1, 2, 3
3 | 5, 6, 7, 4
4 | 1, 2, 3