我在面试时得到了以下问题,这完全让我感到难过,所以我想知道那里是否有人可以帮我解释一下。说我有下表:
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查询(可能是游标?)。任何人都可以帮助我,以防我再次被问到类似的问题吗?感谢。
答案 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
)。