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

SQL Server 2016中按ID分组,用details列末尾两位更新Number列的实现疑问

SQL Server 2016中按ID分组,用details列末尾两位更新Number列的实现疑问

哥们儿,这个需求当然可以实现!你之前的写法问题在于只是逐行处理了带斜杠的details行,但没做到按ID统一更新同组的所有行,所以才会留下同ID但Number值不一致的情况。咱们来一步步解决这个问题:

核心思路

首先得按ID分组,先提取每个ID对应的目标Number值(也就是该ID下带斜杠的details列最后两位),再用这个值批量更新同ID下的所有行,而不是逐行单独更新。

具体实现脚本

这里用CTE(公共表表达式)来先获取每个ID的目标值,再关联原表进行更新,逻辑清晰又容易维护:

-- 先定义每个ID对应的目标Number值
WITH TargetNumberPerID AS (
    SELECT 
        ID,
        RIGHT(details, 2) AS TargetNum
    FROM YourTable
    WHERE details LIKE '%/%' -- 只处理带斜杠的details行
    GROUP BY ID, RIGHT(details, 2)
    -- 注:如果同一个ID下有多个带斜杠的details且末尾两位不同,这里会返回多个行
    -- 这时候需要你根据业务规则调整,比如取最大/最小,或者按行的创建时间排序取最新的
)
-- 执行更新:按ID关联,把同ID的所有行Number统一更新为目标值
UPDATE t
SET t.Number = tv.TargetNum
FROM YourTable t
INNER JOIN TargetNumberPerID tv 
    ON t.ID = tv.ID
-- 可选:只更新Number和目标值不一致的行,减少不必要的更新操作
WHERE t.Number <> tv.TargetNum

处理同一ID下多个带斜杠details的情况

如果你的业务场景中,同一个ID可能存在多个带斜杠的details行,且它们的末尾两位不同,那上面的脚本会因为一个ID对应多个目标值而出错。这时候可以用ROW_NUMBER()来指定取哪一个值,比如取最新的行(假设你有类似CreateTime的时间列):

WITH TargetNumberPerID AS (
    SELECT 
        ID,
        RIGHT(details, 2) AS TargetNum,
        -- 按CreateTime倒序,取每个ID的最新行的目标值
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CreateTime DESC) AS RowRank
    FROM YourTable
    WHERE details LIKE '%/%'
)
UPDATE t
SET t.Number = tv.TargetNum
FROM YourTable t
INNER JOIN TargetNumberPerID tv 
    ON t.ID = tv.ID
WHERE tv.RowRank = 1 -- 只取每个ID的第一个目标值(这里是最新的)
  AND t.Number <> tv.TargetNum

为什么你原来的写法没生效?

你之前的脚本是逐行更新:只给当前details带斜杠的行更新Number,但同ID下其他行(比如details是Temp的那行)完全没被触及,所以才会出现同ID但Number值不一样的情况。而咱们上面的写法是先按ID拿到统一的目标值,再批量更新同ID的所有行,正好解决了这个问题。

备注:内容来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 09:13:09