SQL Server中UPDATE实现分组列求和出错,求更优解决方案
解决SQL Server中按分组聚合更新列的问题
你的错误源于子查询的条件歧义:WHERE A.CD_STYLE = CD_STYLE 里的第二个CD_STYLE没有指定所属表,SQL会默认将其解析为子查询内部表A的列,导致条件恒成立,最终计算的是全表所有行的总和,而非按Style和Color分组的总和。
以下是两种更简便且高效的正确写法:
方法1:使用UPDATE JOIN语法
先预计算分组总和,再通过关联更新原表,性能远优于逐行执行子查询:
UPDATE t SET t.OH_INV_LINE_UNALLOC = agg.TotalQty FROM ECDB.dbo.INVFIFOLAYERING t JOIN ( SELECT CD_STYLE, CD_COLOR, SUM(OH_INV_LINE_ALLOC) AS TotalQty FROM ECDB.dbo.INVFIFOLAYERING GROUP BY CD_STYLE, CD_COLOR ) agg ON t.CD_STYLE = agg.CD_STYLE AND t.CD_COLOR = agg.CD_COLOR
方法2:使用CTE(公共表表达式)
逻辑和方法1一致,写法更直观易读:
WITH StyleColorTotals AS ( SELECT CD_STYLE, CD_COLOR, SUM(OH_INV_LINE_ALLOC) AS TotalQty FROM ECDB.dbo.INVFIFOLAYERING GROUP BY CD_STYLE, CD_COLOR ) UPDATE t SET t.OH_INV_LINE_UNALLOC = sct.TotalQty FROM ECDB.dbo.INVFIFOLAYERING t JOIN StyleColorTotals sct ON t.CD_STYLE = sct.CD_STYLE AND t.CD_COLOR = sct.CD_COLOR
补充说明
- 两种方法仅需扫描两次表(一次计算分组总和,一次关联更新),而你原写法会对每一行执行一次子查询,相当于全表扫描N次(N为表行数),性能差异明显。
- 如果表中存在
Style+Color组合为空的情况,可根据需求添加ISNULL处理,避免目标列被设为NULL。
内容的提问来源于stack exchange,提问作者SQLFinanceGuy123
相关产品推荐
相关产品推荐

