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

SQL表数据更新异常求助:末尾数据移至开头后重复

问题根源拆解

兄弟,你这问题我太熟了!核心原因就是你的UPDATE语句里,目标行(ID1-3566)和要拿来更新的源行(ID3567-7243)之间没有建立精准的对应关系。

当你写UPDATE ... FROM (SELECT ... WHERE Id BETWEEN 3567 AND 7243) dt WHERE Id BETWEEN 1 AND 3566时,数据库会把每个目标行和子查询里的所有源行做匹配——但你没告诉它“目标行1对应源行3567,目标行2对应源行3568”这种规则,数据库就会偷懒,随便选子查询里的一行(通常是第一条也就是ID3567的记录)来更新所有目标行,结果自然就是全变成3567的数据了。

正确的解决思路:给行打序号做匹配

要实现把后面的记录依次移到前面,咱们得给两组行分别生成连续的序号,让第N条源行对应第N条目标行。用ROW_NUMBER()窗口函数就能轻松搞定,看下面的代码:

WITH SourceRows AS (
    SELECT 
        Xwgs, 
        Ywgs,
        -- 给3567-7243的记录按ID升序排,生成从1开始的序号
        ROW_NUMBER() OVER (ORDER BY Id ASC) AS RowNum
    FROM dbo.TABLE 
    WHERE Id BETWEEN 3567 AND 7243
),
TargetRows AS (
    SELECT 
        Id,
        -- 给1-3566的记录按ID升序排,生成从1开始的序号
        ROW_NUMBER() OVER (ORDER BY Id ASC) AS RowNum
    FROM dbo.TABLE 
    WHERE Id BETWEEN 1 AND 3566
)
UPDATE t
SET t.Xwgs = s.Xwgs, t.Ywgs = s.Ywgs
FROM dbo.TABLE t
JOIN TargetRows tr ON t.Id = tr.Id
JOIN SourceRows s ON tr.RowNum = s.RowNum;

为啥这么写?

  • SourceRows:把你要挪的那批数据(3567-7243)按ID从小到大排,给每一行标上1、2、3...的序号,这样最前面的源行(3567)对应序号1,下一个(3568)对应序号2,以此类推。
  • TargetRows:给要被替换的目标行(1-3566)也按ID从小到大标上1、2、3...的序号,目标行1对应序号1,目标行2对应序号2。
  • 最后通过RowNum这个序号把两组行精准关联起来,实现“第1条源行更新第1条目标行,第2条源行更新第2条目标行”的效果。

安全提示!

执行UPDATE前一定要先验证关联是否正确,别直接就更了!可以先跑下面的查询看看对应关系对不对:

SELECT tr.Id AS 目标ID, s.Id AS 源ID, s.Xwgs, s.Ywgs
FROM TargetRows tr
JOIN SourceRows s ON tr.RowNum = s.RowNum;

确认每一行目标ID都对应了正确的源ID,再执行UPDATE就稳了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:48:03