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

将yrstphn表指定重复字段值置为null的SQL/游标实现问询

实现建议:用SQL窗口函数高效解决

嘿,这个需求其实用纯SQL就能搞定,而且比游标高效得多——毕竟数据库天生擅长处理集合操作,没必要用逐行遍历的游标。我给你两种方案,优先推荐第一种:

方案一:窗口函数+CASE表达式(推荐)

这个方法利用ROW_NUMBER()窗口函数控制yr列的显示,再用CASE表达式匹配每个st对应的目标phn值:

SELECT
    -- 只有第一行显示yr,其余行置为null
    CASE WHEN ROW_NUMBER() OVER (ORDER BY st) = 1 THEN yr ELSE NULL END AS yr,
    st,
    -- 根据st匹配对应的phn值
    CASE st
        WHEN 'NV' THEN '1234'
        WHEN 'MD' THEN '2361'
        WHEN 'MA' THEN NULL
    END AS phn
FROM (
    -- 先去重,得到每个st对应的唯一yr(你的数据里yr都是2012,所以去重后每个st一行)
    SELECT DISTINCT st, yr
    FROM yrstphn
) t
ORDER BY st;

运行结果

正好就是你想要的输出:

yrstphn
2012NV1234
nullMD2361
nullMAnull

方案二:游标实现(不推荐,仅作参考)

如果因为特殊场景必须用游标,思路是按st排序后逐行遍历,记录是否是第一行来控制yr的输出,同时给每个st赋值对应的phn:

DECLARE @yr INT, @st VARCHAR(2), @phn VARCHAR(4), @is_first_row BIT = 1;

-- 声明游标,按st排序
DECLARE cur CURSOR FOR
SELECT DISTINCT yr, st
FROM yrstphn
ORDER BY st;

OPEN cur;

-- 创建临时表存储结果
CREATE TABLE #temp_result (yr INT, st VARCHAR(2), phn VARCHAR(4));

FETCH NEXT FROM cur INTO @yr, @st;
WHILE @@FETCH_STATUS = 0
BEGIN
    -- 给phn赋值
    SET @phn = CASE @st
        WHEN 'NV' THEN '1234'
        WHEN 'MD' THEN '2361'
        WHEN 'MA' THEN NULL
    END;

    -- 第一行保留yr,其余行置为null
    INSERT INTO #temp_result
    VALUES (CASE WHEN @is_first_row = 1 THEN @yr ELSE NULL END, @st, @phn);

    SET @is_first_row = 0;
    FETCH NEXT FROM cur INTO @yr, @st;
END;

CLOSE cur;
DEALLOCATE cur;

-- 查询结果
SELECT * FROM #temp_result;
DROP TABLE #temp_result;

为什么不推荐游标?

游标是逐行处理数据,性能远不如集合式的SQL操作,而且代码更繁琐,维护成本高。除非你的业务逻辑有非常特殊的逐行依赖场景,否则优先用方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:33:02