如何更新同sales_key下仅保留一条记录金额其余置0?
解决每个sales_key仅保留一条记录金额的更新方案
原SQL的问题在于,通过QTY和PRD_CD的最小值组合筛选,无法保证每个sales_key下仅匹配到唯一一条记录——比如同一sales_key下可能存在多条记录同时满足QTY为最小值且PRD_CD为最小值,导致保留多条记录的金额;或者该组合逻辑本身不符合你实际要保留的记录规则。
推荐使用窗口函数ROW_NUMBER()来实现需求,它能确保每个sales_key下仅标记一条目标记录:
方法一:使用CTE(通用表表达式)关联更新
WITH RankedSales AS ( SELECT SALES_KEY, PRD_CD, QTY, NET_TTL, NET_TTL_TAX, MKT_TAX_AMT, -- 按sales_key分组,每组内按PRD_CD、QTY排序生成序号,可根据需求调整排序字段 ROW_NUMBER() OVER (PARTITION BY SALES_KEY ORDER BY PRD_CD, QTY) AS rn FROM #TEMPSALES2 ) UPDATE #TEMPSALES2 SET NET_TTL = CASE WHEN rs.rn = 1 THEN rs.NET_TTL ELSE 0 END, NET_TTL_TAX = CASE WHEN rs.rn = 1 THEN rs.NET_TTL_TAX ELSE 0 END, MKT_TAX_AMT = CASE WHEN rs.rn = 1 THEN rs.MKT_TAX_AMT ELSE 0 END FROM #TEMPSALES2 ts JOIN RankedSales rs ON ts.SALES_KEY = rs.SALES_KEY AND ts.PRD_CD = rs.PRD_CD AND ts.QTY = rs.QTY;
方法二:直接子查询生成序号后更新(更简洁)
UPDATE ts SET NET_TTL = CASE WHEN ts.rn = 1 THEN ts.NET_TTL ELSE 0 END, NET_TTL_TAX = CASE WHEN ts.rn = 1 THEN ts.NET_TTL_TAX ELSE 0 END, MKT_TAX_AMT = CASE WHEN ts.rn = 1 THEN ts.MKT_TAX_AMT ELSE 0 END FROM ( SELECT *, -- 可根据实际需求修改排序规则,比如按创建时间、ID等确定保留哪一条 ROW_NUMBER() OVER (PARTITION BY SALES_KEY ORDER BY PRD_CD, QTY) AS rn FROM #TEMPSALES2 ) ts;
说明
ROW_NUMBER()会为每个SALES_KEY分组内的记录生成唯一序号,rn=1的记录就是每组要保留金额的那条。- 可以修改
ORDER BY后的字段,来指定保留每组中的哪一条记录(比如按ID、创建时间等),确保符合你的业务需求。 - 如果表有唯一主键(如
ID),关联时优先使用主键,避免因字段重复导致的关联错误。
内容的提问来源于stack exchange,提问作者MR.G
相关产品推荐
相关产品推荐

