胡泽亮
实际生产中处理过户导致的业务与财务稽核差异的一种方法
胡泽亮
中国电信河北分公司,河北 石家庄 050000
通信企业进行业务稽核,对收入的逻辑差异进行分析时常受到过户数据的干扰。提供了一种简单的方法通过数据库过滤过户数据,在稽核工作中使用数据库工具,提高稽核工作的信息化水平。
业务稽核;数据库;过户
在通信企业的业务与财务稽核工作中,验证预存平衡是其中很重要的一环,最常用的逻辑差异稽核公式为:起初余额+当月缴费-当月消费=期末余额。
日常处理过程一般是细化颗粒度到账户级,将每个用户套用一遍以上的公式以便找出存在逻辑差异的账户。但是找出的差异账户大量是当月发生过户操作,实际分析后发现可以正负相抵并不是真正的差异账户。本文介绍了一种使用数据库脚本消除这种过户产生差异的简易方法。
首先我们举例分析过户导致逻辑差异的原理。
实例1:用户A在当月操作过户从账户1转入账户2,同时有10元钱也从账户1转入账户2,那么用户与账户关系表中会有以下记录(见表1)。
表1
账户用户是否有效变更日期 1A否20180402 2A是20180402
假定账户1和账户2下没有其他用户,用户A当月的期初余额为10,当月也没有缴费和消费,当月逻辑差异公式为(见表2)。
表2
账户用户期初余额缴费消费期末余额逻辑差异 1A1000010 2A00010﹣10
虽然账户1和账户2都有差异,但是两个账户的逻辑差异正好正负相抵,差异合计为0。由此我们可以认为通过用户A可以找到账户1和账户2之间的关联,账户1和账户2的集合当月逻辑差异为0。
在这里我们引入一个账户组的概念,当月有过户关系的账户的合集。如果将现有差异按照账户组的细粒度进行全量比对,就可剔除其中因过户导致的合理差异。在实际生产中过户关系远比以上例子复杂,可能涉及多个用户多个账户多次过户,因此我们需要将以上情况考虑周全避免引入额外的差异。
以下是复杂场景下的两个例子,我们可以试着分析如何找到关联,组成我们需要的账户组。
实例2:用户A当月有两次过户操作,分别是携带10元从账户1转入账户2,又携带20元从账户2转入账户3,那么用户与账户关系表中会有以下的记录(见表3)。
表3
账户用户是否有效变更日期 1A否20180402 2A否20180403 3A是20180403
假定账户1、账户2、账户3下没有其他用户,当月也没有缴费和消费,当月逻辑差异公式为(见表4)。
表4
用户期初余额缴费消费期末余额逻辑差异 A1000010 A1000010 A00020﹣20
实例3:用户A当月携带10元从账户1转入账户2,用户B当月携带20元从账户2转入账户3,那么用户与账户关系表中会有以下的记录(见表5)。
表5
假定账户1、账户2、账户3下没有其他用户,当月也没有缴费和消费,当月逻辑差异公式为(见表6)。
表6
账户用户期初余额缴费消费期末余额逻辑差异 1A1000010 2A、B1000010 3B00020﹣20
在实例2中虽然用户做了两次过户操作,但是仍然可以通过用户A一次性关联到账户1、账户2、账户3。在实例3中则要复杂一些,先通过用户A关联到账户1和账户2,再通过账户2找到用户B,通过用户B发现账户2和账户3是关联账户,最终形成账户1、账户2、账户3的账户组。
在实际生产中我们无法预知实例3中的迭代关联会出现多少次,因此需要使用脚本穷举,直到找齐所有的关联账户。
在通信企业中,Oracle是常见的数据库,因此本文的脚本遵循Oracle数据库的编码格式,其他数据库脚本可以参考修改。
首先建立中间表临时存储找到的关联账户,其中ACCT_ID为起始账户id,SERV_ID为根据起始账户id找到的用户id,ACCT_ID1为根据用户id关联到的账户id,note为迭代查找的次数。
create table HZL_TEMP0702_3
( city_code VARCHAR2(4),
ACCT_ID NUMBER(12),
SERV_ID NUMBER(12),
ACCT_ID1 NUMBER(12),
NOTE NUMBER
)
根据用户和账户关系提取相关账户并插入中间表
declare[1]
i NUMBER ;
v1 number ;
v2 number ;
cursor c1 is
select city_code,acct_id from HZL_TEMP0702_2 group by city_code,acct_id ;
begin
for rec in c1 loop[2]
i:=0 ;
v1:=0 ;
v2:=0 ;
insert into HZL_TEMP0702_3
select t1.city_code,rec.acct_id,t1.serv_id,t1.acct_id,0
from month_serv_acct t1,month_serv_acct t2
where t1.fee_date=to_char(add_months(sysdate,-1),'yyyymm')
and t2.fee_date=to_char(add_months(sysdate,-1),'yyyymm')
and t1.city_code=rec.city_code
and t2.city_code=rec.city_code
and t2.acct_id =rec.acct_id and (to_char(t2.state_date,'yyyymm')=to_char(add_months(sysdate,-1),'yyyymm') or (t2.state='10A' and to_char(t2.state_date,'yyyymm')<=to_char(add_months(sysdate,-1),'yyyymm')))
and t2.serv_id=t1.serv_id and (to_char(t1.state_date,'yyyymm')=to_char(add_months(sysdate,-1),'yyyymm') or (t1.state='10A' and to_char(t1.state_date,'yyyymm')<=to_char(add_months(sysdate,-1),'yyyymm')))
group by t1.city_code,rec.acct_id,t1.serv_id,t1.acct_id ;
commit ;
begin
loop
i:=i+1;
insert into HZL_TEMP0702_3
select t1.city_code,rec.acct_id,t1.serv_id,t1.acct_id,i
from month_serv_acct t1,month_serv_acct t2
where t1.fee_date=to_char(add_months(sysdate,-1),'yyyymm')
and t2.fee_date=to_char(add_months(sysdate,-1),'yyyymm')
and t1.city_code=rec.city_code
and t2.city_code=rec.city_code
and t2.acct_id in (select distinct acct_id1 from HZL_TEMP0702_3 where acct_id=rec.acct_id and note=i-1) and (to_char(t2.state_date,'yyyymm')=to_char(add_months(sysdate,-1),'yyyymm') or (t2.state='10A' and to_char(t2.state_date,'yyyymm')<=to_char(add_months(sysdate,-1),'yyyymm')))
and t2.serv_id=t1.serv_id and (to_char(t1.state_date,'yyyymm')=to_char(add_months(sysdate,-1),'yyyymm') or (t1.state='10A' and to_char(t1.state_date,'yyyymm')<=to_char(add_months(sysdate,-1),'yyyymm')))
group by t1.city_code,rec.acct_id,t1.serv_id,t1.acct_id ;
commit ;
select count(1) into v2
from HZL_TEMP0702_3
where acct_id=rec.acct_id
and note=i ;
select count(1) into v1
from HZL_TEMP0702_3
where acct_id=rec.acct_id
and note=i-1 ;
exit when v2=v1 ;
end loop ;
commit ;
end ;
end loop ;
commit;
end ;
在这个脚本中我们加入了循环,循环的结束条件是找到的关联账户数量不再增加,实现相关账户的穷举。
由于最后一次循环的结果与倒数第二次的结果一致,所以需要做一次排重汇总。
create table HZL_TEMP0702_31 as
select acct_id, serv_id, acct_id1
from HZL_TEMP0702_3
group by acct_id, serv_id, acct_id1
最终HZL_TEMP0702_31这张表中ACCT_ID是起始账户id,ACCT_ID1是根据起始账户id找到的所有关联账户id,形成账户组。我们以根据账户组为细粒度分组汇总已有的差异账户,当账户组下所有账户逻辑差异合计为0,可以认为是过户导致的合理差异,反之则需要进一步核实是其他什么原因导致的非合理差异。
通过以上脚本分析4月份某个地市差异,执行前该地市以账户为细粒度共有差异2 958条,执行脚本后发现剔除过户导致的合理差异91条,如图1所示。
图 1
从脚本沉淀的临时结果表hzl_temp0416_31,随机抽取其中起始id为13169200的账户组进行分析,如图2所示。
图 2
起始账户id=13169200共关联到两个用户id,分别是13944547和15214681,其中用户id=13944547的过户操作涉及账户13169200、152142279、152144117,可以根据用户与账户关系表中的记录证明,如图3所示。
图 3
用户id=15214681的过户操作涉及账户13169200、152142810,可以根据用户与账户关系表中的记录证明,如图4所示。
图 4
起始账户id=13169200的账户组当月逻辑差异公式,如图5所示。
图 5
图5展示的结果表明该账户组下所有关联账户当月逻辑差异合计为0,证明之前第二节中的实例3是正确的。
经过实际验证可见该方法最终执行结果与预期一致,满足生产要求并具备可操作性,不失为一种能够排除过户导致逻辑差异的简便易行的方法。
[1]Oracle Database Online Documentation 11g Release 2 (11.2) / SQL Language Reference[Z].
[2]Expert Indexing in Oracle Database 11g[M].
A Method of Dealing with the Difference between Business and Financial Audits in Actual Production
Hu Zeliang
China Telecom Hebei Branch, Hebei Shijiazhuang 050000
Communication companies conduct business audits, and the analysis of the logical differences in revenue is often interrupted by transfer data. The paper provides a simple way to filter data through the database, use database tools in the audit work, and improve the information level of audit work.
business audit; database; transfer
F275;TP311.13
A