基于指定条件查找父级CustomerNum的SQL实现求助
查找符合条件的父级CustomerNum实现方案
问题背景
现有[dbo].[VwCustomer]视图结构及数据如下:
| CustomerNum | ParentCustomerNum | IsPlatform |
|---|---|---|
| 132 | 0 | 1 |
| 253 | 132 | 0 |
| 2041 | 253 | 0 |
| 2132 | 253 | 0 |
| 521 | 132 | 0 |
| 551 | 132 | 0 |
| 594 | 132 | 1 |
| 5642 | 5434 | 1 |
| 5811 | 5434 | 1 |
查找条件
- 根据指定
CustomerNum查找记录,若其父级ParentCustomerNum>0且IsPlatform=1,返回该父级 - 若指定
CustomerNum的父级ParentCustomerNum=0且IsPlatform=1,返回自身(根节点平台) - 若指定
CustomerNum的父级ParentCustomerNum>0且IsPlatform≠1,则向上遍历父级,重复检查上述条件
尝试的错误CTE代码
WITH cte AS ( SELECT CustomerId, ISSCustId, CustomerName, CustomerNum, IsPlatform, CustomerNum As TopParent FROM [dbo].[VwCustomer] --WHERE ParentCustomerNum = 0 UNION ALL SELECT T.CustomerId, T.ISSCustId, T.CustomerName, T.CustomerNum, T.IsPlatform, cte.TopParent FROM [dbo].[VwCustomer] As T JOIN cte ON T.ParentCustomerNum = cte.CustomerNum ) SELECT * FROM cte WHERE cte.CustomerNum = 253 ORDER BY TopParent DESC;
预期结果示例
- 查询
CustomerNum=594时,其父级132满足IsPlatform=1,停止遍历并返回该父级记录 - 若父级
IsPlatform=0(如查询CustomerNum=2041),则继续遍历到132,检查其状态并返回
正确SQL实现方案
使用递归CTE从指定节点向上遍历,直到找到第一个IsPlatform=1的节点或根节点,核心是控制递归终止条件:
DECLARE @TargetCustomerNum INT = 2041; -- 替换为你要查询的CustomerNum WITH RecursiveCustomer AS ( -- 起始节点:指定的目标客户 SELECT CustomerNum, ParentCustomerNum, IsPlatform, 1 AS Level -- 记录遍历层级,可选 FROM [dbo].[VwCustomer] WHERE CustomerNum = @TargetCustomerNum UNION ALL -- 递归向上遍历父级 SELECT c.CustomerNum, c.ParentCustomerNum, c.IsPlatform, rc.Level + 1 AS Level FROM [dbo].[VwCustomer] c INNER JOIN RecursiveCustomer rc ON c.CustomerNum = rc.ParentCustomerNum -- 终止条件:还没找到IsPlatform=1的节点,继续递归 WHERE rc.IsPlatform != 1 ) -- 取遍历结果中第一个IsPlatform=1的节点,或者根节点(如果根节点不是平台则返回根节点) SELECT TOP 1 CustomerNum AS TargetParentCustomerNum, ParentCustomerNum, IsPlatform FROM RecursiveCustomer ORDER BY Level DESC; -- 从最深层级(最上层父级)开始找,找到第一个符合条件的就返回
代码说明
- 起始CTE:先定位到指定的目标
CustomerNum记录 - 递归部分:每次向上关联父级记录,仅当当前节点不是平台(
IsPlatform !=1)时继续递归,避免不必要的遍历 - 最终查询:按遍历层级倒序排序,取第一条记录——也就是向上找到的第一个
IsPlatform=1的父节点,如果所有父级都不是平台,则返回根节点(ParentCustomerNum=0的节点)
测试验证
- 当
@TargetCustomerNum=594时,递归层级为1(自身),其父级是132,递归到132时,由于594的IsPlatform=1,递归终止,最终返回132的记录 - 当
@TargetCustomerNum=2041时,递归层级依次为2041(Level1)→253(Level2)→132(Level3),132的IsPlatform=1,最终返回132的记录
内容的提问来源于stack exchange,提问作者DT_2
相关产品推荐
相关产品推荐

