生成层次结构

时间:2013-08-09 18:14:28

标签: sql

我在面试时得到了以下问题,这完全让我感到难过,所以我想知道那里是否有人可以帮我解释一下。说我有下表:

employees
--------------------------
id | name     | reportsTo
--------------------------
 1 | Alex     | 2
 2 | Bob      | NULL
 3 | Charlie  | 5
 4 | David    | 2
 5 | Edward   | 8
 6 | Frank    | 2
 7 | Gary     | 8
 8 | Harry    | 2
 9 | Ian      | 8

问题是编写一个SQL查询,该查询返回一个表,其中包含每个员工姓名的列,以及一个列,显示该组织中该员工的人数以上:即。,

hierarchy
--------------------------
name     | hierarchyLevel
--------------------------
Alex     | 1
Bob      | 0
Charlie  | 3
David    | 1
Edward   | 2
Frank    | 1
Gary     | 2
Harry    | 1
Ian      | 2

我甚至无法弄清楚从哪里开始将其写为SQL查询(可能是游标?)。任何人都可以帮助我,以防我再次被问到类似的问题吗?感谢。

1 个答案:

答案 0 :(得分:2)

最简单的例子是使用(真实或临时)表,并一次添加一个级别(fiddle):

INSERT INTO hierarchy
SELECT id, name, 0
FROM employees
WHERE reportsTo IS NULL;

WHILE ((SELECT COUNT(1) FROM employees) <> (SELECT COUNT(1) FROM hierarchy))
BEGIN
    INSERT INTO hierarchy
    SELECT e.id, e.name, h.hierarchylevel + 1
    FROM employees e
    INNER JOIN hierarchy h ON e.reportsTo = h.id
    AND NOT EXISTS(SELECT 1 FROM hierarchy hh WHERE hh.id = e.id)
END

每个RDBMS的其他解决方案略有不同。作为一个示例,在SQL Server中,您可以使用递归CTE来扩展它(fiddle):

;WITH expanded AS
(
    SELECT id, name, 0 AS level
    FROM employees
    WHERE reportsTo IS NULL
    UNION ALL
    SELECT e.id, e.name, level + 1 AS level
    FROM expanded x
    INNER JOIN employees e ON e.reportsTo = x.id
)
SELECT * 
FROM expanded
ORDER BY id

其他解决方案包括递归存储过程,甚至使用动态SQL迭代地增加连接数,直到每个人都被考虑在内。

当然,所有这些例子都假设没有周期,每个人都可以追溯到一个头部(reportsTo = NULL)。