Update语句余数处理:税额分配至A10501行并保留两位小数
修正后的税额分配SQL查询
原查询存在两个核心问题:一是临时表的RowNum未对应A10501的行号,导致余数分配逻辑错误;二是先除法后取整的计算顺序会引入多位小数误差。以下是修正后的代码:
-- 替换为目标发票编号 DECLARE @target_invcnmbr NVARCHAR(50) = 'INV001'; -- 临时表存储A20601的总税额和A10501的行数 CREATE TABLE #temp_allocation ( INVCNMBR NVARCHAR(50), TotalTax DECIMAL(18, 2), RowCount INT ); INSERT INTO #temp_allocation (INVCNMBR, TotalTax, RowCount) SELECT a.INVCNMBR, ROUND(SUM(a.TXDTLAMT), 2) AS TotalTax, COUNT(p.INVCNMBR) AS RowCount FROM A20601 a JOIN A10501 p ON a.INVCNMBR = p.INVCNMBR WHERE a.INVCNMBR = @target_invcnmbr GROUP BY a.INVCNMBR; -- 给A10501的行生成序号,执行分配更新 WITH A10501_Ranked AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum -- 可根据实际业务调整排序逻辑 FROM A10501 WHERE INVCNMBR = @target_invcnmbr ) UPDATE A10501_Ranked SET FEETXAMT = ROUND(FEETXAMT + CASE WHEN RowNum < RowCount THEN FLOOR(TotalTax * 100 / RowCount) / 100 ELSE TotalTax - (FLOOR(TotalTax * 100 / RowCount) / 100) * (RowCount - 1) END, 2), OTFTXAMT = ROUND(OTFTXAMT + CASE WHEN RowNum < RowCount THEN FLOOR(TotalTax * 100 / RowCount) / 100 ELSE TotalTax - (FLOOR(TotalTax * 100 / RowCount) / 100) * (RowCount - 1) END, 2) FROM A10501_Ranked JOIN #temp_allocation t ON A10501_Ranked.INVCNMBR = t.INVCNMBR; DROP TABLE #temp_allocation;
关键修正说明:
- 行号绑定A10501:通过CTE生成目标表每行的序号,确保余数能精准追加到最后一行。
- 消除小数误差:将金额转换为分(乘以100)后取整计算基础分配额,再转回元,彻底避免多位小数问题。
- 精准余数计算:用总税额减去前N-1行的基础分配额总和,直接得到最后一行金额,保证总额完全匹配要求。
内容的提问来源于stack exchange,提问作者CC_G
相关产品推荐
相关产品推荐

