带参数的存储过程中每一行的递归 CTE

Posted

技术标签:

【中文标题】带参数的存储过程中每一行的递归 CTE【英文标题】:Recursive CTE on every row in a stored procedure with parameter 【发布时间】:2021-07-18 07:47:30 【问题描述】:

我有一个名为 AccountNode 的表。 其中列 nodeId 在 ParentNodeId 列中具有父级。

AccountNode
nodeId   | ParentNodeId  |  Flag | SetId | 

1           2              N     1 
2           115            N     1 
115         4              N     1
4           5              Y     1
12          13             N     1 
13          14             N     1 
14          15             Y     1 
23          24             N     1 
25          30             Y     1 

我需要什么: 我需要获取标志为 Y 的每个节点 id 的父节点(这是我们需要停止递归 cte 的地方),对于作为参数传递给过程的 setId。

eg : 
input: 
for set_id : 1 
output: 

nodeId    parentNode  flag    set_id
1           5           Y        1 
12          15          Y        1 
25          30          Y        1 

我已经编写了一个递归 cte 来获取节点 id 的父节点,但是我在为 setid 编写它时遇到了麻烦,其中 ,我需要遍历 setid 中的所有 nodeIds,以获取 parentNode。 这是我的 sql:

with accountNode_cte  (nodeId, parentNode, flag, set_id) as 
(select nodeId , parentNode, flag, set_id) from accountNode where nodeId = '1' 
union all
select accountNode.nodeId, accountNode.parentNode, accountNode.flag, accountNode.set_id from 
accountNode 
join accountNode_cte on accountNode.nodeId = accountNode_cte.parentNode
and accountNode_cte.flag !='Y')
select * from accountNode_cte where flag='Y'

我对编写 sql 程序很陌生,不知道该怎么做

【问题讨论】:

一旦查询工作正常,PL/SQL 过程从何而来? 这个查询给出了 nodeId 的正确结果。当一个 setId 出现在它下面有多个 nodeIds 的图片时被卡住了。 【参考方案1】:

从起始节点遍历节点层次结构,记住起始点,跟踪级别,在起始点级别行内取最大值。

with accountNode_cte(p, l, nodeId, parentNode, flag, set_id) as (
  select parentNodeId p, 1 l, nodeId , parentNodeId, flag, set_id 
  from accountNode 
  where flag = 'Y' and set_id = 1
  
  union all
  
  select p, l+1, accountNode.nodeId, accountNode.parentNodeId, accountNode.flag, accountNode.set_id 
  from accountNode 
  join accountNode_cte on accountNode.parentnodeId = accountNode_cte.NodeId
)
select distinct first_value(nodeId) over(partition by p order by l desc) nodeId, p parentnId
from accountNode_cte;

db<>fiddle

【讨论】:

以上是关于带参数的存储过程中每一行的递归 CTE的主要内容,如果未能解决你的问题,请参考以下文章

存储过程——公用表表达式(CTE)

SQL,While循环,递归存储过程或游标中哪个更快?

sql递归cte在视图中不能正常工作

【存储过程】存储过程中所有定义的参数都要赋值么?

怎样在Delphi中实现在运行中实现带参数的存储过程?

SQL Server 如何执行 带参数的 存储过程