1 前言 
  在程序设计过程中,往往碰到比较两个记录集的差异。如,判定原来传入的订单资料与后来传入的订单资料之间的差异,并且将差异的数据显示给用户。 
                                                                                              实现的方式有多种,如编程存储过程返回游标,在存储过程中对两批数据进行比较...等等,当然返回差异数据的方式多种多样,既可以是游标,又可以临时表或其它方式。 
  本文主要论述利用Oracle的MINUS函数和OVER函数,直接通过视图实现两个记录集的比较。 
  
  2 实现步骤 
  2.1 利用MINUS函数,判定原始表与比较表的增量差异<设,两个记录集分别以表的方式存在,为表A和表B。其中,A表为原始表,B表为后来产生的比较表,即要与A表进行比较的数据表> 
  增量差异指,A中存在的记录,哪些在B表中没有的,也就是说,A表的记录被修改或删除 
  
  2.2 利用MINUS函数,判定比较表与原始表的增量差异 
  即B表中存在的记录,哪些在A表中没有,也就是说,B表新增的或A表修改的记录 
  
  2.3 连接A-B的增量差异表和B-A的增量差异表,利用OVER函数判定数据重复的次数 
  假如数据重复次数为2,则该记录的标识为“修改”; 
  假如数据重复次数为1,且出现在A-B的增量差异表中,则该记录的标识为“删除”; 
  假如数据重复次数为1,且出现在B-A的增量差异表中,则该记录的标识为“新增” 
  
  3 实例演练 
  --3.1 创建数据表和实例环境<设原始记录集为数据表A,比较记录集为数据表B,当然实际应用过程中,参与比较的通常是视图,不会是数据表> 
  --测试环境配置 
  Drop Table a; 
  Drop Table b; 
  Create Table a(a1 Numeric(28),a2 Varchar2(10)); 
  Create Table b(b1 nUMERIC(28),b2 VarChar2(10)); 
  Insert Into a Values (1,'a'); 
  Insert Into a Values (2,'ba'); 
  Insert Into a Values (3,'ca'); 
  Insert Into a Values (4,'da'); 
  Insert Into b Values (1,'a'); 
  Insert Into b Values (2,'bba'); 
  Insert Into b Values (3,'ca'); 
  Insert Into b Values (5,'dda'); 
  Insert Into b Values (6,'Eda'); 
  Commit; 
  Select * from a; 
  Select * From b; 
  
  --3.2 创建比较视图 
  Create Or replace View VW_Test_Minus as 
    --标识重复出现的次数(次数=1->删除或新增,次数=2->修改) 
    SELECT A1 
       ,a2 
       ,t --A表/B表标识 
       ,ROW_NUMBER() OVER (PARTITION BY A1 ORDER BY A1) RN --记录重复次数 
     FROM 
      ( 
        Select a1,a2,'A表' T  --查看A表存在,B表没有的记录(修改或删除) 
          from 
           ( 
             (Select * from a ) 
             Minus 
             (Select * From b) 
           ) a2b 
        Union --联合A表与B表不相同的记录集 
        Select b1,b2,'B表' T  --查看B表存在,A表没有的记录(修改或新增) 
          from 
           ( 
             (Select * from b ) 
             Minus 
             (Select * From a) 
             ) b2a 
       ) F; 
  / 
  --3.3 比较结果集 
  Select a1 
    ,a2 
    ,T 
    ,Rn 
    ,Decode(Rn --标识记录变化 
     ,2,'修改' 
     ,Decode(T 
       ,'A表','删除' 
       ,'新增')) Mark 
    From VW_Test_Minus 
     Where Rn=(Select Count(*) From VW_Test_Minus V Where V.a1=VW_Test_Minus.a1) 
  ; 
  4 后记 
  许多DBA都非凡痛恨那些希望通过一句SELECT语句来实现复杂用户需求的编码人员,使用MINUS和OVER函数来实现数据比较,在执行效率上,可能会存在问题。
                          
  本文的目的,并不在于讨论程序运行的效率,而在于抛砖引玉,引起大家对OVER函数的重视和对MINUS函数的认知。