不用游标也能巧查断号票据
王攀(山东省烟台市审计局)
【发布时间:2014年03月03日】
字号:【大】 【中】 【小】

前不久,审计署网站刊登了甘肃省陇南市审计局梁小虎同志“巧用游标查找断号票据”一文,分析了传统断号筛查语句的缺陷,并撰写了利用游标实现连续票据中查找出断号票据的方法,笔者深受启发。但在我们日常工作中,一是除社保、地税、银行等大型项目外,使用大规模数据库查询的概率不大,二是能够提笔撰写游标的一线审计工作人员不多,即便设计通用模板,在没有专业人员配合下,真正能用到、用好、自行调整游标语句的人更少。因此,笔者整理了一个在小规模数据中方便使用的,仅用子查询技术实现查找断号数据的方法,结构简单、思路清晰,即使新进审计人员也能迅速上手掌握,与广大审计同仁探讨。
我们把票据表视为同样的两个表A和B,设计实验数据5条。这样,对于A表中的任何一个数,在B表中都有对应值,如A表中有1,B表中也有1,如下图:

但对于A表中任何一个数加1,B表中就有可能有对应值,如A表中的1,在B表中就有2(1+1),


也有可能没有对应值,如对于A表中的2,在B表中就没有3(2+1),那么这个值(2+1)就是断号的起点,


以某地国土分局开具票据为例,原始数据如下图


内层查询语句就是:
 select 票据号+1 as 断号起点 from 某国土
          where 票据号+1 not in (select 票据号 from表名)
当查询到A表最后一条数据时,B表中找不到比这个数据大1的数,会发生溢出错误,需要设置where条件,补充语句为:
select 票据号+1 as 断号起点 from 某国土
    where 票据号+1 not in (select 票据号 from 某国土)
     and 票据号< (select MAX(票据号) from 某国土)
刚才我们查了断号的起点,断号的终点就是B表中比刚才查出的断号起点大的所有的数中最小的数,比如3是断号的起点,比3大的数有5、6、9,其中最小的数是5,所以5就是断号的终点,但是5在票据表中是存在的,所以5-1就是真正的票据终点。
因此构建外层查询语句:  
select a.断号起点,(select MIN(票据号)-1 from 某国土
                    where 票据号>a.断号起点) as 断号终点
  from
 (select 票据号+1 as 断号起点 from 某国土
    where 票据号+1 not in (select 票据号 from 某国土)
    and 票据号< (select MAX(票据号) from 某国土))a
     order by 1
执行结果中存在重复数据,

这是因为执收部门开具的一张票据可能涉及多个收入事项,在录入系统时按照收入事项分别填入,导致多条数据使用一个票据号,如下图所示


因此需要加入distinct条件,调整后完整语句如下:
select distinct a.断号起点,(select MIN(票据号)-1 from 某国土
                    where 票据号>a.断号起点) as 断号终点
  from
 (select 票据号+1 as 断号起点 from 某国土
    where 票据号+1 not in (select 票据号 from 某国土)
    and 票据号< (select MAX(票据号) from 某国土))a
     order by 1
执行结果如下图


全部语句不超过6行,稍微了解SQL语句的人都能上手。审计人员在不同数据库中使用该语句时,仅需要修改表名和票据号的列名即可。同时根据执行结果,落实断号原因,或索取作废票据,或查实相应领取票据,审查有无票据延压、出借、代开、私设小金库等问题情况。(王攀)
【关闭】    【打印】