Разрешение иерархии в таблице базы данных - PullRequest
0 голосов
/ 11 января 2019

У меня есть таблица оргструктуры, которая смоделирована следующим образом:

+-------------+------------+-----------------+
| Employee_ID | Manager_ID | Department_Name |
+-------------+------------+-----------------+
|           1 |          2 | Level1          |
|           2 |          3 | Level2          |
|           3 |            | Level3          |
+-------------+------------+-----------------+

Итак, каждый сотрудник ссылается на другую строку в цепочке, которая представляет организационную диаграмму. Для всех сотрудников эта модель используется для представления иерархии.

Однако для целей отчетности нам нужно запросить денормализованную таблицу, то есть где данные представлены следующим образом:

+-------------+--------+--------+--------+
| Employee_ID | ORG_1  | ORG_2  | ORG_3  |
+-------------+--------+--------+--------+
|           1 | Level1 |        |        |
|           2 | Level1 | Level2 |        |
|           3 | Level1 | Level2 | Level3 |
+-------------+--------+--------+--------+

со многими столбцами ORG_x, необходимыми для представления всех уровней, которые могут быть найдены. Затем вы можете делать простые группировки, такие как GROUP BY ORG_1, ORG_2, ORG_3. Обратите внимание, что можно разумно предположить максимальное количество уровней.

Итак, вот мой вопрос: поскольку база данных находится на сервере SQL, могу ли я ожидать, что это осуществимо в Transact-SQL, чтобы я мог построить представление?

Прежде чем я начну изучать T-SQL, я хочу убедиться, что я на правильном пути.

(Кстати, если да, меня заинтересуют рекомендации для хорошего урока!)

Спасибо!

R.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Да, шаблон, который у вас есть, известен как список смежности. Это очень распространено. Недостатком является то, что для построения дерева требуется рекурсия, что может привести к проблемам с производительностью на больших наборах. Еще один более быстрый подход - использовать модель Nested Sets . Сначала это немного менее интуитивно понятно, но как только вы поймете концепцию, это будет очень просто.

Независимо от того, какую модель вы используете для хранения ваших данных, для получения необходимого вам денормализованного формата потребуется динамическая сводная таблица или динамическая кросс-таблица.

0 голосов
/ 11 января 2019

Я бы использовал общие табличные выражения с PIVOT :

DECLARE @T TABLE
(
    Employee_ID int,
    Manager_ID int,
    Department_Name varchar(10)
);

INSERT @T VALUES
(1,2,'Level 1'),
(2,3,'Level 2'),
(3,NULL,'Level 3');

WITH C AS (
    SELECT Employee_ID, Manager_ID, Department_Name
    FROM @T
    UNION ALL
    SELECT T.Employee_ID, T.Manager_ID, C.Department_Name
    FROM C
    JOIN @T T ON C.Manager_ID=T.Employee_ID
), N AS (
    SELECT ROW_NUMBER() OVER (PARTITION BY Employee_ID ORDER BY Department_Name) N, *
    FROM C
)
SELECT Employee_ID, [1] ORG_1, [2] ORG_2, [3] ORG_3
FROM N
PIVOT (MAX(Department_Name) FOR N IN ([1],[2],[3])) P
ORDER BY Employee_ID

Результат:

Employee_ID ORG_1      ORG_2      ORG_3
----------- ---------- ---------- ----------
1           Level 1    NULL       NULL
2           Level 1    Level 2    NULL
3           Level 1    Level 2    Level 3

Примечание: если у вас есть только 3 уровня, вы также можете сделать простой 3 х JOIN

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