如何将SELECT结果作为参数传入CTE并UNION ALL所有CTE查询结果
实现方法
不需要手动遍历GroupId做循环+UNION ALL,SQL本身是集合查询语言,直接把你返回GroupId列表的基础查询接入CTE做关联,就能一次性得到所有结果,性能远好于逐行循环的写法。
场景1:非递归CTE(和你示例逻辑一致的简单场景)
把你原有的返回GroupId的查询封装为第一个CTE,直接和业务表做关联匹配即可,完全等价于逐个传参再合并结果的效果:
WITH GroupIdList AS ( -- 此处替换为你自己的、返回GroupId列的SELECT查询语句 SELECT GroupId FROM [Group] ), GroupCTE AS ( SELECT gc.* FROM GroupCross gc INNER JOIN GroupIdList gil ON gc.GroupCrossId = gil.GroupId ) SELECT * FROM GroupCTE
场景2:递归CTE(层级查询等复杂逻辑场景)
如果你的CTE是递归结构(比如根据示例里的GroupCrossParentId字段查询每个GroupId对应的完整父/子层级链,这也是这类需求最常见的复杂用法),直接把GroupId列表作为递归锚点的初始数据源即可:
WITH GroupIdList AS ( -- 此处替换为你自己的、返回GroupId列的SELECT查询语句 SELECT GroupId FROM [Group] ), GroupCTE AS ( -- 锚点:加载所有待处理GroupId对应的初始行 SELECT gc.* FROM GroupCross gc INNER JOIN GroupIdList gil ON gc.GroupCrossId = gil.GroupId UNION ALL -- 递归部分:保留你原有的递归逻辑即可,示例为向上查询父节点 SELECT gc.* FROM GroupCross gc INNER JOIN GroupCTE cte ON gc.GroupCrossId = cte.GroupCrossParentId ) -- 不同初始GroupId可能递归到相同节点,加DISTINCT去重,按需选用 SELECT DISTINCT * FROM GroupCTE
注意事项
- 不要使用游标、WHILE循环逐行取ID执行、再插入临时表最后合并,这类写法代码冗余、性能差,上述集合关联的写法由数据库查询优化器统一做执行计划优化,效率高很多。
- 如果你的CTE包含多段中间计算逻辑,不需要改动原有核心逻辑,只要把
GroupIdList作为首个CTE,在最终匹配GroupId的环节做关联即可。
针对你给出的示例数据,上述写法执行后返回结果和逐ID执行再UNION ALL的结果完全一致:
| GroupCrossId | GroupCrossName | GroupCrossParentId |
|---|---|---|
| 10 | OCVJK | 1799 |
| 450 | OBYT | 486 |
| 265 | ONKU | 105 |
| 266 | ONCU | 84 |
内容的提问来源于stack exchange,提问作者NoStressDeveloper
相关产品推荐
相关产品推荐

