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