У меня есть набор данных из таблицы (TableA), которая относится к себе через TableB. Родители в TableA имеют детей в TableA. У этих детей тоже могут быть дети. Здесь ничего удивительного.
У меня есть набор строк верхнего уровня из TableA, с которым мне нужно работать. Прежде чем я смогу работать с этими строками, у меня должна быть под рукой каждая дочерняя строка. Я должен иметь возможность работать с каждой строкой верхнего уровня TableA (и ее дочерними элементами) как можно быстрее в моем приложении.
Я не могу найти способ сделать это.
Использование рекурсивного CTE (TableA верхнего уровня, установленного как привязка, TableB->TableA объединение как объединение), не соответствует требованиям. Полный набор верхнего уровня из TableA возвращается в CTE, прежде чем он будет работать на уровне 2 дочерних элементов. Затем он работает на уровне 3. Затем на уровне 4 и т. Д. Поскольку мой набор верхнего уровня составляет более 400 000 строк, мое клиентское приложение не может начать работать со строками, пока ВЕСЬ набор данных не будет загружен на сервер.
Мне нужен способ получше. Я пробовал передавать клиенту плоский набор TableA строк верхнего уровня и заставлять клиента многократно выдавать рекурсивный оператор CTE для каждой TableA строки верхнего уровня. Это действительно работает. Но слишком много шума. Постоянная скорость извлечения строк слишком велика из-за многократной повторной выдачи операторов.
Мне нужно креативное решение.
Фрагмент используемого мной CTE для каждой записи. В этом примере TableA - это Member, а TableB - это MemberReplacement. Я вырвал большую часть оператора select посередине и большую часть соединений.
WITH T_MemberRecurse
(
MemberId,
IncludedMemberId,
Level
) AS (
SELECT Member.Id,
Member.Id,
0
FROM MemberInput
INNER JOIN MemberInputItem
ON MemberInputItem.MemberInputId = MemberInput.Id
INNER JOIN Member
ON Member.Id = MemberInputItem.MemberId
UNION ALL
SELECT T_MemberRecurse.MemberId,
Member2.Id,
Level + 1
FROM T_MemberRecurse
INNER JOIN Member
ON Member.Id = T_MemberRecurse.IncludedMemberId
INNER JOIN MemberReplacement
ON MemberReplacement.MemberId = Member.Id
INNER JOIN Member Member2
ON Member2.Id = MemberReplacement.OriginalMemberId
)
SELECT Member.Id,
T_MemberRecurse.IncludedMemberId,
T_MemberRecurse.Level,
FROM MemberInput
INNER JOIN LotsOfTables