我正在使用SQL Server 2008 R2 SP1。我想通过“走树”来递归地为某个组织单位找到第一个非空经理。
我有一个包含组织单位“ ORG”的表,一个包含每个组织的父母的表。“ ORG”中的部门,将其称为表“ORG_PARENTS
”,其中一个表包含每个组织部门的经理,将其称为“ ORG_MANAGERS
”。
ORG具有一列ORG_ID:
ORG_ID
1
2
3
ORG_PARENTS有两列。
ORG_ID, ORG_PARENT
1, NULL
2, 1
3, 2
管理器有两列。
ORG_ID, MANAGER
1, John Doe
2, Jane Doe
3, NULL
我正在尝试创建一个递归查询,该查询将为某个组织单位找到第一个非空管理器。
基本上,如果我今天查询经理ORG_ID = 3,我将得到NULL。
SELECT MANAGER FROM ORG_MANAGERS WHERE ORG_ID = '3'
我希望查询使用ORG_PARENTS
表获取ORG_ID = 3
的父级,在这种情况下,获取“ 2”并针对ORG_ID = 2
的ORG_MANAGERS
表重复查询,并在此示例中返回“ Jane Doe”。
如果查询还返回NULL,我想使用ORG_ID = 2
的父级(即ORG_ID = 1
,以此类推)重复该过程。
到目前为止,我的CTE尝试失败了,一个例子是:
WITH BOSS (MANAGER, ORG_ID, ORG_PARENT)
AS
( SELECT m.MANAGER, m.ORG_ID, p.ORG_PARENT
FROM dbo.MANAGERS m INNER JOIN
dbo.ORG_PARENTS p ON p.ORG_ID = m.ORG_ID
UNION ALL
SELECT m1.MANAGER, m1.ORG_ID, b.ORG_PARENT
FROM BOSS b
INNER JOIN dbo.MANAGERS m1 ON m1.ORG_ID = b.ORG_PARENT
)
SELECT * FROM BOSS WHERE ORG_ID = 3
它返回:
消息530,级别16,状态1,第4行语句终止。在语句完成之前,最大递归100已用尽。
MANAGER ORG_ID ORG_PARENT
NULL 3 2
您需要跟踪开始时使用的原始ID。试试这个:
DECLARE @ORG_PARENTS TABLE (ORG_ID INT, ORG_PARENT INT )
DECLARE @MANAGERS TABLE (ORG_ID INT, MANAGER VARCHAR(100))
INSERT @ORG_PARENTS (ORG_ID, ORG_PARENT)
VALUES (1, NULL)
, (2, 1)
, (3, 2)
INSERT @MANAGERS (ORG_ID, MANAGER)
VALUES (1, 'John Doe')
, (2, 'Jane Doe')
, (3, NULL)
;
WITH BOSS
AS
(
SELECT m.MANAGER, m.ORG_ID AS ORI, m.ORG_ID, p.ORG_PARENT, 1 cnt
FROM @MANAGERS m
INNER JOIN @ORG_PARENTS p
ON p.ORG_ID = m.ORG_ID
UNION ALL
SELECT m1.MANAGER, b.ORI, m1.ORG_ID, OP.ORG_PARENT, cnt +1
FROM BOSS b
INNER JOIN @ORG_PARENTS AS OP
ON OP.ORG_ID = b.ORG_PARENT
INNER JOIN @MANAGERS m1
ON m1.ORG_ID = OP.ORG_ID
)
SELECT *
FROM BOSS
WHERE ORI = 3
结果是:
+----------+-----+--------+------------+-----+
| MANAGER | ORI | ORG_ID | ORG_PARENT | cnt |
+----------+-----+--------+------------+-----+
| NULL | 3 | 3 | 2 | 1 |
| Jane Doe | 3 | 2 | 1 | 2 |
| John Doe | 3 | 1 | NULL | 3 |
+----------+-----+--------+------------+-----+
一般提示:
不要预定义CTE的列;这是不必要的,并且使维护变得烦人。
使用递归CTE时,始终要保留一个计数器,这样您就可以限制递归性,并且可以跟踪自己的深度。
编辑:
顺便说一句,如果您想要第一个不是null的管理器,则可以这样做(例如,有很多方法):
SELECT BOSS.*
FROM BOSS
INNER JOIN (
SELECT BOSS.ORI
, MIN(BOSS.cnt) cnt
FROM BOSS
WHERE BOSS.MANAGER IS NOT NULL
GROUP BY BOSS.ORI
) X
ON X.ORI = BOSS.ORI
AND X.cnt = BOSS.cnt
WHERE BOSS.ORI IN (3)
问题内容: 我期望以下内容返回所有元组,将层次结构中的每个父级解析到顶部,但它仅返回最低级别(在查询中指定了其ID)。如何为给定的level_id返回整棵树? 问题答案: 首先,如果您确实是祖父母,则应该如此。其次,您在查询的递归一半中的(隐式)连接条件是向后的,您想让父级脱离,而不是:
嗨,我有一个map-reduce程序,它在每个递归步骤中获取reducer的输出。但我还需要在每次递归中输出另一个结果。 输入1--- 输出1--- 输出2--- 输出3--- 作为我需要的最终输出:输出11,输出22,输出33,输出44和输出4 像这样,每个步骤都有两个输出文件,其中一个用于下一次迭代,另一个用于输出。 我正在使用序列文件作为文本输入格式。 任何帮助,谢谢。
问题内容: 以下问题的正确答案: 如果我没有记错的话,那是在11.2.0.3或更高版本中修复的错误。(无论如何不再支持11.2.0.1.11.2.0.4是唯一仍受支持的11.2版本)-@a_horse_with_no_name 错误号为11840579,已在11.2.0.3和12.1.0.1中进行了修复-@a_horse_with_no_name问题 I have a table The foll
我想递归地删除一个链表。我想到了如何迭代地做到这一点,但我对如何做到这一点很好奇。到目前为止我有: 我定义的地方 如果需要,我可以去掉头部,但我不知道如何去掉身体或尾巴,然后正确地缝合列表,更不用说递归地做了。我该如何进行?为什么这样不行? 编辑:删除问号并替换为我认为可行的代码。
本文向大家介绍OCaml 具有模式匹配的递归列表处理,包括了OCaml 具有模式匹配的递归列表处理的使用技巧和注意事项,需要的朋友参考一下 示例 在这里,我们演示了如何使用OCaml的模式匹配语法来递归处理列表。 在这种情况下,模式[]匹配空列表,而hd::tl匹配任何具有至少一个元素的列表,hd并将列表的第一个元素分配给,列表的其余部分(可以为空)分配给tl。 请注意,这hd::tl是一种非常通
像阿西莫夫机器人,所有递归算法必须服从三个重要的定律: 递归算法必须具有基本情况。 递归算法必须改变其状态并向基本情况靠近。 递归算法必须以递归方式调用自身。 让我们更详细地看看每一个定律,看看它如何在 listsum 算法中使用。首先,基本情况是算法停止递归的条件。基本情况通常是足够小以直接求解的问题。在listsum 算法中,基本情况是长度为 1 的列表。 为了遵守第二定律,我们必须将算法向基