You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL Server中通过循环查询获取指定保单的最终关联保单号

解决方案

方法1:使用递归CTE(隐式循环逻辑)

大部分现代数据库(如SQL Server、PostgreSQL、MySQL 8.0+)支持递归CTE,这是处理层级追溯问题的常用方式,内部通过循环遍历层级关系:

WITH RECURSIVE policy_hierarchy AS (
    -- 初始查询:获取目标Policy_No的初始记录
    SELECT 
        Policy_No, 
        Old_Policy_No,
        Old_Policy_No AS final_old_policy
    FROM tbl_account
    WHERE Policy_No IN ('A', 'C', 'E', 'G')
    
    UNION ALL
    
    -- 递归查询:逐层追溯直到Old_Policy_No为Null
    SELECT 
        ph.Policy_No, 
        ta.Old_Policy_No,
        ta.Old_Policy_No AS final_old_policy
    FROM policy_hierarchy ph
    JOIN tbl_account ta ON ph.final_old_policy = ta.Policy_No
    WHERE ta.Old_Policy_No IS NOT NULL
)
-- 取每个Policy_No的最后一层记录(即Old_Policy_No为Null前的有效值)
SELECT 
    Policy_No, 
    final_old_policy AS Old_Policy_No
FROM policy_hierarchy
WHERE final_old_policy IN (
    SELECT Policy_No FROM tbl_account WHERE Old_Policy_No IS NULL
)
ORDER BY Policy_No;

方法2:显式循环的存储过程(以MySQL为例)

如果要求必须写显式循环的代码,可以用存储过程实现,通过循环逐个追溯每个目标Policy_No的最终上级:

DELIMITER //

CREATE PROCEDURE GetFinalOldPolicy()
BEGIN
    -- 创建临时表存储结果
    CREATE TEMPORARY TABLE IF NOT EXISTS temp_result (
        Policy_No VARCHAR(10),
        Old_Policy_No VARCHAR(10)
    );
    
    -- 定义变量
    DECLARE target_policy VARCHAR(10);
    DECLARE current_old_policy VARCHAR(10);
    DECLARE done INT DEFAULT 0;
    
    -- 游标遍历目标Policy_No
    DECLARE policy_cursor CURSOR FOR 
        SELECT Policy_No FROM tbl_account WHERE Policy_No IN ('A', 'C', 'E', 'G');
    
    -- 游标结束处理
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
    -- 打开游标
    OPEN policy_cursor;
    
    -- 循环处理每个目标Policy
    policy_loop: LOOP
        FETCH policy_cursor INTO target_policy;
        IF done = 1 THEN
            LEAVE policy_loop;
        END IF;
        
        -- 初始化当前旧保单号
        SELECT Old_Policy_No INTO current_old_policy FROM tbl_account WHERE Policy_No = target_policy;
        
        -- 循环追溯直到Old_Policy_No为Null
        WHILE current_old_policy IS NOT NULL DO
            SET @next_old_policy = (SELECT Old_Policy_No FROM tbl_account WHERE Policy_No = current_old_policy);
            IF @next_old_policy IS NULL THEN
                LEAVE;
            END IF;
            SET current_old_policy = @next_old_policy;
        END WHILE;
        
        -- 将结果插入临时表
        INSERT INTO temp_result (Policy_No, Old_Policy_No) VALUES (target_policy, current_old_policy);
    END LOOP policy_loop;
    
    -- 关闭游标
    CLOSE policy_cursor;
    
    -- 查询结果
    SELECT * FROM temp_result ORDER BY Policy_No;
    
    -- 删除临时表
    DROP TEMPORARY TABLE IF EXISTS temp_result;
END //

DELIMITER ;

-- 调用存储过程
CALL GetFinalOldPolicy();

说明

  • 递归CTE写法简洁高效,适合支持该特性的数据库;
  • 显式循环的存储过程兼容性更好,适合不支持递归CTE的旧版本数据库;
  • 两种方法都能输出你需要的目标结果,可根据使用的数据库类型选择。

内容的提问来源于stack exchange,提问作者dodo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:16:09