解决数据库表中的层次结构

时间:2019-01-11 14:00:11

标签: sql-server database tsql

我有一个如下所示的组织结构图表:

+-------------+------------+-----------------+
| 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 Server上,我可以期望这在Transact-SQL中是可行的,以便我可以建立视图吗?

在我开始学习T-SQL之前,我想确保自己走在正确的轨道上。

(顺便说一句,如果是的话,我会对一个好的教程的建议感兴趣!)

谢谢!

R。

2 个答案:

答案 0 :(得分:1)

我将common table expressionsPIVOT一起使用:

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 x JOIN

答案 1 :(得分:1)

是的,这里的模式称为邻接表。这是很常见的。缺点是构建树需要您使用递归,这会导致大型集合上的性能问题。另一种更快的方法是使用Nested Sets模型。刚开始时它有点不那么直观,但是一旦您理解了这个概念,它就会变得非常容易。

无论使用哪种模型存储数据,都将需要动态数据透视表或动态交叉表才能以所需的非规范化格式获取数据。