SQL更新临时表rank_no异常:仅设为1而非预期序列值
问题排查与解决方案
你的UPDATE语句出现所有rank_no被更新为1的核心原因是子查询与目标表未建立正确的关联关系。
原语句中,子查询x从#CARD中筛选数据并生成排名,但在UPDATE逻辑里仅判断x.no_rank IS NOT NULL,没有指定#CARD与x之间的行匹配规则。这会导致数据库执行笛卡尔积关联——目标表的每一行都会匹配子查询的所有行,最终更新时随机选取某一行的no_rank值(此处恰好都取到了1),完全不符合按pt_id分组排序的预期。
方案1:添加明确的关联条件
在UPDATE的JOIN逻辑中,通过唯一标识组合(比如pt_id+chg_tot_amt,若表有主键则优先用主键)将目标表与子查询的行一一对应:
UPDATE c SET c.rank_no = x.no_rank FROM #CARD c INNER JOIN ( SELECT pt_id, chg_tot_amt, ROW_NUMBER() OVER (PARTITION BY pt_id ORDER BY chg_tot_amt) AS no_rank FROM #CARD WHERE noproc = 2 ) x ON c.pt_id = x.pt_id AND c.chg_tot_amt = x.chg_tot_amt -- 若存在唯一主键,替换为主键列关联更可靠 WHERE x.no_rank IS NOT NULL
方案2:使用CTE(公共表表达式)更新
CTE可直接基于原表生成排名,无需额外关联,逻辑更清晰直观:
WITH RankedCards AS ( SELECT rank_no, ROW_NUMBER() OVER (PARTITION BY pt_id ORDER BY chg_tot_amt) AS no_rank FROM #CARD WHERE noproc = 2 ) UPDATE RankedCards SET rank_no = no_rank;
验证结果
执行修正后的语句后,rank_no会按pt_id分组、chg_tot_amt升序生成1、2的序号,符合预期:
pt_id rank_no chg_tot_amt no_rank -------------------------------------- 99999990 1 4722.3 1 99999990 2 17712.6 2 99999991 1 13643.26 1 99999991 2 15851.24 2 ...
内容的提问来源于stack exchange,提问作者Cindy Fuentes
相关产品推荐
相关产品推荐

