假设我有一张员工表,其中包含我公司每位员工的记录,以及一份主管专栏(如下所示)。我想准备一份报告,其中列出了监管线中每个步骤的名称和标题。例如,对于迪克罗宾斯,1d#15,我想在他的“指挥系统”中列出每个主管,一直到总统,大奶酪。我想避免使用游标,但如果这是唯一的方法,那就没关系。
id fname lname title supervisorid
1 big cheese president 1
2 jim william vice president 1
3 sally carr vice president 1
4 ryan allan senior manager 2
5 mike miller manager 4
6 bill bryan manager 4
7 cathy maddy foreman 5
8 sean johnson senior mechanic 7
9 andrew koll senior mechanic 7
10 sarah ryans mechanic 8
11 dana bond mechanic 9
12 chris mcall technician 10
13 hannah ryans technician 10
14 matthew miller technician 11
15 dick robbins technician 11
真正的数据可能不会超过10级...但我宁愿不只是做10次外连接...我希望有比这更好的东西,并且比游标更少参与。
感谢您的帮助。
答案 0 :(得分:20)
这基本上是我在OP评论中链接到的问题的接受答案的一个端口。
你可以使用公用表表达式
WITH Family As
(
SELECT e.id, e.supervisorid, 0 as Depth
FROM Employee e
WHEREid = @SupervisorID
UNION All
SELECT e2.ID, e2.supervisorid, Depth + 1
FROM Employee e2
JOIN Family
On Family.id = e2.supervisorid
)
SELECT*
FROM Family
更多信息:
答案 1 :(得分:0)
一些递归函数,它返回主管(如果有的话)或null。也可以是一个调用自身的SP,并使用UNION。
答案 2 :(得分:0)
您可能对物化路径"感兴趣解决方案,它稍微对表进行规范化,但可以在任何类型的SQL数据库上使用,并且可以防止您不必进行递归查询。实际上,它甚至可以在无SQL数据库上使用。
您只需要添加一个包含对象整个祖先的列。例如,下表包含一个名为tree_path
的列:
+----+-----------+----------+----------+
| id | value | parent | tree_path|
+----+-----------+----------+----------+
| 1 | Some Text | 0 | |
| 2 | Some Text | 0 | |
| 3 | Some Text | 2 | -2-|
| 4 | Some Text | 2 | -2-|
| 5 | Some Text | 3 | -2-3-|
| 6 | Some Text | 3 | -2-3-|
| 7 | Some Text | 1 | -1-|
+----+-----------+----------+----------+
选择id = 2的记录的所有后代如下所示:
SELECT * FROM comment_table WHERE tree_path LIKE '-2-%' ORDER BY tree_path ASC
要构建树,您可以按tree_path
排序,以获得一个非常容易转换为树的数组。
您也可以索引tree_path
,并且当通配符不在开头时可以使用索引。
例如,tree_path LIKE '-2-%'
可以使用索引,但tree_path LIKE
% - 2 - '`不能。
答案 3 :(得分:0)
SQL是用于执行 set 操作的语言,而递归不是其中的一种。此外,许多数据库系统在使用存储过程作为安全措施的递归上有一些限制,以防止流氓代码耗尽宝贵的服务器资源。
因此,在使用SQL时,请始终考虑'flat',而不是“ hierarchical”。因此,我强烈建议您使用已建议的'tree_path'方法。我使用了相同的方法,它非常出色而且非常关键,非常坚固。