负向事实与冲正是什么
负向事实与冲正指退款、撤销、更正发生时,不修改也不删除原记录,而是插入一条度量取负的新行,并通过原交易号引用被冲正的那笔。流水保持只插不改,任何时点回看都能完整审计;日终或任意区间汇总时,正负行自然抵消得到净额。直接改原行金额会破坏审计链,也无法回答「这笔钱什么时候退的」。
基本信息
| 基本原则 | 只插不改,原行永久保留 |
|---|---|
| 冲正方式 | 插入负向度量行,并引用原交易号 |
| 净额算法 | 同一业务键 sum(amt),正负自相抵 |
| 必备字段 | 原单引用、冲正类型、冲正发生时间 |
| 区分要求 | 冲正行与原交易行的业务时间要分开记录 |
典型使用场景
- 退款:退款成功时插入负金额支付行,与原支付抵消
- 订单撤销:整单作废插入整单负向行,保留原因
- 折扣更正:优惠算错时用负向行冲平,再补一条正确金额
- 重复扣款修复:对多扣的那笔插一条等额负行
- 跨月冲正:上月的错误在本月冲正,两个月的报表各自可解释
- 账户调账:余额差异用负向事实记录,避免直接改期初
净额汇总与冲正
净额汇总与冲正
-- 净额:正负抵消,任意区间都成立
SELECT order_id, sum(pay_amt) AS net_amt
FROM fact_payment
GROUP BY order_id;
-- 冲正行插入:金额取负,原单引用必填
INSERT INTO fact_payment
(pay_id, order_id, biz_date, pay_amt, pay_type, ref_pay_id)
VALUES ('R20261013001', 'O20261001001', '2026-10-13',
-199.00, 'refund', 'P20261001001');
-- 冲正量监控:单日冲正金额占比异常升高要人工介入
SELECT biz_date,
sum(case when pay_amt < 0 then -pay_amt else 0 end) AS refund_amt,
sum(pay_amt) AS net_amt
FROM fact_payment
GROUP BY biz_date;冲正与直接更新对照
| 维度 | 插入负向行 | 直接更新原行 |
|---|---|---|
| 可审计性 | 完整保留正负流水 | 原值丢失,无法还原 |
| 净额正确性 | sum 即为净额 | 看似一致,但无过程记录 |
| 时点还原 | 可回答任意日期的净额 | 只能回答当前值 |
| 跨期处理 | 各期报表自洽 | 上期报表被动改写,已披露数据失真 |
| 实现复杂度 | 需处理重复冲正 | 表面简单,长期隐患大 |
冲正行要引用原交易号,才能从净额一路追回每一笔正负记录。同时要防重复冲正:同原单同类型的冲正只允许一条,可用唯一约束兜住,否则重复退款会静默把金额冲成负数。