Так у меня есть набор таблиц вдоль линий следующегорекурсия в SQL
cables:
id (integer) | name (char)
knots:
id (integer) | name (char)
cableKnotAttachments:
id (integer) | sourceCableId (integer) | targetKnotId (integer)
cableCableAttachments:
id (integer) | sourceCableId (integer) | targetCableId (integer)
Если Cable
может быть присоединен к нескольким другим Cable
с, а также несколько Knot
сек и Knot
может быть присоединен к несколько Cable
s.
Учитывая, что Cables.Id
, мне нужно найти все Knots
, которые находятся в пределах этого Cable
детей. Мы говорим, что узел является ребенком Cable
, если он либо непосредственно прикреплен, либо является ребенком любого Cable
, который прикреплен к Cable
.
Моя попытка до сих пор выглядит следующим образом:
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;
В псевдо-коде, что было бы неплохо:
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;
}
Но это распространяется только на один уровень рекурсии (без меня просто повторять, что ad nauseam).
Есть ли простой способ сделать это в SQL Server. Можно предположить, что это нецелесообразно проверять все Knot
s в виде обратной проверки.
Редактировать: Добавление некоторых выборочных данных для процветания. Предполагая, что у нас есть Cables
с id
s {1, 2, ..., 4}
; и Knots
с 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
В каком контексте мы имеем:
cableId | childKnots
1 | 2, 3, 4, 1
2 | 4, 1, 2, 3
3 | 5, 6, 7, 4
4 | 1, 2, 3
Возможный дубликат [Sql сервера КТР и пример рекурсии] (http://stackoverflow.com/questions/14274942/sql-server-cte-and -recursion-example) –
Похоже, вам понадобится как минимум 1 cte, чтобы найти все кабели, а затем присоединиться, чтобы получить все узлы. Примеры данных были бы очень полезны здесь – Matt