Применить значение таблицы Sister ко всем отношениям родитель / потомок в основной таблице - PullRequest
1 голос
/ 05 апреля 2019

ФОН:

У меня довольно сложный сценарий (по крайней мере, для меня), в котором я хочу вернуть данные из 2 таблиц, в одной из которых содержатся родительские / дочерние или иерархические отношения, и только другие члены семьи могут ссылаться на другие Таблица.

Предположим, у меня есть 3 таблицы со следующими данными:

ТАБЛИЦА 1 - Определяет родительские / дочерние отношения с именем. Может быть несколько уровней, не только родитель и потомок, но и полная иерархия

Id | Table1Name | ParentId
---------------------------
1  | Root       | NULL
2  | Child1     | 1
3  | Chile2     | 1
4  | Root2      | NULL
5  | Child1-2   | 4
6  | Child2-2   | 4

ТАБЛИЦА 2 - дочерняя таблица ТАБЛИЦЫ 3 ниже. Также ссылки ТАБЛИЦА 1 выше

Id | Table2Name | Table1Id | Table3Id
-------------------------------------------
20 | Test1      | 2        | 40
21 | Test2      | 2        | 40
22 | Test3      | 3        | 40
23 | Test4      | 3        | 40
24 | Test5      | 5        | 41
25 | Test6      | 5        | 41
26 | Test7      | 6        | 41
27 | Test8      | 6        | 41

ТАБЛИЦА 3 - Родительская таблица - просто включена в качестве ссылки для этого примера, не используется в запросе

Id | Table3Name
-----------------
40 | Parent1
41 | Parent2



ВОПРОС:

Я пытаюсь разработать запрос, который будет перечислять ВСЕ строки из ТАБЛИЦЫ 1, но будет включать в себя Table3Id, связанный со всеми записями для этих родительских / дочерних отношений. Поэтому для этого примера я ожидаю, что набор результатов будет выглядеть следующим образом:

Id | Table1Name | ParentId | Table3Id
--------------------------------------
1  | Root       | NULL     | 40
2  | Child1     | 1        | 40
3  | Chile2     | 1        | 40
4  | Root2      | NULL     | 41
5  | Child1-2   | 4        | 41
6  | Child2-2   | 4        | 41

Обратите внимание, что строки 1 и 4 выше не имеют прямого отношения к ТАБЛИЦЕ 2, но имеют косвенное отношение через строки (2 и 3) и (5 и 6) соответственно.

Я уверен, что есть способ сделать это, но я не вижу правильной комбинации кода для этого.

1 Ответ

2 голосов
/ 05 апреля 2019

Вы используете рекурсивный CTE, начиная со всех дочерних элементов, у которых есть совпадение в Таблице 2, а затем перемещаются вверх по дереву.

WITH recHierarchy AS
(
    SELECT t1.Id, t1.ParentId, t2.Table3Id
      FROM #table1 t1
     INNER
      JOIN #table2 t2
        ON t1.Id = t2.Table1Id

     UNION ALL

     SELECT parent.Id, parent.ParentId, child.Table3Id
       FROM #table1 parent
       JOIN recHierarchy child
         ON child.ParentId = parent.Id
)
SELECT DISTINCT Id, ParentId, Table3Id FROM recHierarchy

Это также будет работать, если в Таблице 1 есть иерархия, например:

Id | Table1Name | ParentId
---------------------------
7  | Root3       | NULL
8  | Child3-1    | 7
9  | Chile3-1-1  | 8

И Table3Id определяется только для Id = 9.

Рабочий пример для dbfiddle .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...