Skip to content

凭证核对:总账科目余额 vs 明细账发生额

用途:核对总账科目余额与明细账(含辅助核算)发生额是否勾稽一致。凭证录入后,若辅助核算没挂、或凭证被手工修改过,总账和明细账会脱节——报表没问题,一查明细就对不上。

业务口径

  • 总账余额:科目汇总后的余额(按科目)
  • 明细账发生额:逐笔凭证的发生额(含辅助核算维度)
  • 勾稽关系:科目余额 = 明细发生额合计(借贷相抵);带辅助核算的科目,余额 = 各辅助维度明细合计

T-SQL 版本(SQL Server)

sql
-- 用途:核对总账科目余额与明细账发生额(含辅助核算)
-- 方言:T-SQL (SQL Server)
-- 参数:@year 年度, @period 期间(0=期初,1-12=月份)
DECLARE @year INT = 2026, @period INT = 7;

WITH gl AS (  -- 总账科目余额
    SELECT cCode, SUM(md) AS gl_amt
    FROM GL_balance                  -- 示意表:总账余额表
    WHERE iYear = @year AND iPeriod = @period
    GROUP BY cCode
),
vch AS (  -- 凭证明细发生额(按科目汇总)
    SELECT cCode, SUM(md) AS vch_amt
    FROM GL_accvch                  -- 示意表:凭证及明细账表
    WHERE iYear = @year AND iPeriod = @period
    GROUP BY cCode
)
SELECT
    COALESCE(g.cCode, v.cCode) AS 科目,
    ISNULL(g.gl_amt, 0) AS 总账余额,
    ISNULL(v.vch_amt, 0) AS 明细发生额,
    ISNULL(g.gl_amt, 0) - ISNULL(v.vch_amt, 0) AS 差额
FROM gl g
FULL OUTER JOIN vch v ON g.cCode = v.cCode
WHERE ABS(ISNULL(g.gl_amt, 0) - ISNULL(v.vch_amt, 0)) > 0.01
ORDER BY ABS(ISNULL(g.gl_amt, 0) - ISNULL(v.vch_amt, 0)) DESC;

Oracle 版本

sql
-- 用途:核对总账科目余额与明细账发生额(含辅助核算)
-- 方言:Oracle
-- 参数::year 年度, :period 期间
WITH gl AS (  -- 总账科目余额
    SELECT cCode, SUM(md) AS gl_amt
    FROM GL_balance                  -- 示意表
    WHERE iYear = :year AND iPeriod = :period
    GROUP BY cCode
),
vch AS (  -- 凭证明细发生额
    SELECT cCode, SUM(md) AS vch_amt
    FROM GL_accvch                  -- 示意表
    WHERE iYear = :year AND iPeriod = :period
    GROUP BY cCode
)
SELECT
    COALESCE(g.cCode, v.cCode) AS 科目,
    NVL(g.gl_amt, 0) AS 总账余额,
    NVL(v.vch_amt, 0) AS 明细发生额,
    NVL(g.gl_amt, 0) - NVL(v.vch_amt, 0) AS 差额
FROM gl g
FULL OUTER JOIN vch v ON g.cCode = v.cCode
WHERE ABS(NVL(g.gl_amt, 0) - NVL(v.vch_amt, 0)) > 0.01
ORDER BY ABS(NVL(g.gl_amt, 0) - NVL(v.vch_amt, 0)) DESC;

辅助核算专项核对(带辅助维度的科目)

sql
-- 用途:核对带辅助核算科目 余额 vs 辅助明细合计
-- 方言:T-SQL (SQL Server)
-- 参数:@code 科目编码, @year 年度, @period 期间
DECLARE @code VARCHAR(20) = '1122', @year INT = 2026, @period INT = 7;

WITH gl AS (  -- 科目余额(含辅助)
    SELECT cCode, SUM(md) AS gl_amt
    FROM GL_balance
    WHERE cCode = @code AND iYear = @year AND iPeriod = @period
    GROUP BY cCode
),
aux AS (  -- 辅助核算明细合计
    SELECT cCode, SUM(md) AS aux_amt
    FROM GL_accass                  -- 示意表:辅助核算明细表
    WHERE cCode = @code AND iYear = @year AND iPeriod = @period
    GROUP BY cCode
)
SELECT
    g.cCode AS 科目,
    g.gl_amt AS 科目余额,
    ISNULL(a.aux_amt, 0) AS 辅助明细合计,
    g.gl_amt - ISNULL(a.aux_amt, 0) AS 差额
FROM gl g
LEFT JOIN aux a ON g.cCode = a.cCode
WHERE ABS(g.gl_amt - ISNULL(a.aux_amt, 0)) > 0.01;

Oracle 写法差异ISNULLNVL,其余结构一致。

语法差异速查

T-SQLOracle
判空ISNULL(x,0)NVL(x,0)
参数@var 变量:var 绑定变量
FULL OUTER JOIN一致一致

常见差异原因

  1. 凭证漏挂辅助核算:录凭证时没选往来单位/部门,明细在「无辅助」下
  2. 凭证被手工改过:改金额没同步改辅助明细
  3. 期初不平:期初导入时辅助明细没跟着导入(见案例库-期初迁移)

排查建议

  • 先跑总账 vs 明细,再跑辅助核算专项,两层都过才算平
  • 差异金额等于某张凭证金额时,直接按金额反查凭证
  • 月结前跑一遍,把漏挂辅助的凭证补上再结账

内容已脱敏 · 不含客户名称与真实金额

微信公众号显林的随笔

ERP 实施笔记 · 案例复盘 · 资料更新提醒
微信搜一搜「显林的随笔」即可关注

二维码待补
(林哥提供后替换)