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

使用ROW_NUMBER更新CTE未达预期,求SQL Server 2016解决方案

问题原因分析

你的问题核心在于ROW_NUMBER()的排序字段没有唯一性:
在CTE的ROW_NUMBER定义中,ORDER BY a04.AccountNumber ASC,但因为已经用PARTITION BY a04.AccountNumber分区,同一分区内的AccountNumber值完全相同(都是777782),这会导致SQL Server无法确定明确的排序规则,RN的分配是随机不稳定的——每次执行时,相同AccountNumber的行可能被分配不同的RN值,最终导致你更新了错误的行。

修正方案

修改ROW_NUMBER的ORDER BY子句,使用具有唯一性的字段(比如RecordId)来确定稳定的排序规则。比如你想保留最新的RecordId(最大的那个),就按RecordId降序排序,这样RN=1始终对应最大的RecordId行,RN>1就是需要置为非激活的行。

修正后的完整SQL代码:

;WITH CTE AS (
    SELECT a04.RecordId, a04.AccountNumber, a04.PhoneType, a04.Active
        , RN = ROW_NUMBER() OVER(PARTITION BY a04.AccountNumber ORDER BY a04.RecordId DESC)
    FROM dbo.A04_AccountPhones a04
    WHERE a04.PhoneType = 'RRT'
    AND a04.AccountNumber = 777782
)
UPDATE c
SET c.Active = 0
FROM CTE c
WHERE c.RN > 1;

-- 验证更新结果
SELECT a04.RecordId, a04.AccountNumber, a04.PhoneType, a04.Active, a04.AreaCode, a04.TelephoneNumber
    , RN = ROW_NUMBER() OVER(PARTITION BY a04.AccountNumber ORDER BY a04.RecordId DESC)
FROM dbo.A04_AccountPhones a04
WHERE a04.PhoneType = 'RRT'
AND a04.AccountNumber = 777782
ORDER BY a04.AccountNumber ASC, a04.RecordId DESC;
验证结果

更新后你会看到:

  • RecordId=5803964(RN=1)的Active保持1
  • RecordId=5802727(RN=2)和5533020(RN=3)的Active被置为0
    完全符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:42:43