这与问题:SQL Statement for Reconciliation非常相关,但更加复杂。SQL Statement for reconciliation with different operators
下面给出的模式:
create table TBL1 (ID varchar2(100) primary key not null, MATCH_CRITERIA timestamp);
create table TBL2 (ID varchar2(100) primary key not null, MATCH_CRITERIA timestamp);
create table TBL_RESULT (ID varchar2(100) primary key not null, TBL1_ID varchar2(100), TBL2_ID varchar2(100));
create unique index UK_TBL_RESULT_TBL1_ID on TBL_RESULT(TBL1_ID);
create unique index UK_TBL_RESULT_TBL2_ID on TBL_RESULT(TBL2_ID);
insert into TBL1 VALUES('1', to_date('01/26/2012 20:00:00', 'mm/dd/yyyy hh24:mi:ss'));
insert into TBL1 VALUES('2', to_date('01/26/2012 20:05:00', 'mm/dd/yyyy hh24:mi:ss'));
insert into TBL2 VALUES('3', to_date('01/26/2012 19:59:00', 'mm/dd/yyyy hh24:mi:ss'));
insert into TBL2 VALUES('4', to_date('01/26/2012 20:04:00', 'mm/dd/yyyy hh24:mi:ss'));
我们目前查询:
INSERT INTO TBL_RESULT (ID, TBL1_ID, TBL2_ID)
SELECT rawtohex(sys_guid()),t1.id,t2.id
FROM
(SELECT t1.match_criteria,t1.id, row_number() OVER (PARTITION BY t1.match_criteria ORDER BY t1.id) rn
FROM tbl1 t1) t1,
(SELECT t2.match_criteria,t2.id, row_number() OVER (PARTITION BY t2.match_criteria ORDER BY t2.id) rn
FROM tbl2 t2) t2
WHERE t1.match_criteria between t2.match_criteria - (10/1440) AND t2.match_criteria + (10/1440)
AND t1.rn=t2.rn
它的输出:
| ID | TBL1_ID | TBL2_ID |
| '1' | '1' | '3' |
| '2' | '1' | '4' |
| '3' | '2' | '3' |
| '4' | '2' | '4' |
如您所见,结果不符合唯一性约束(重复TBL1_ID /重复TBL2_ID)。这是因为:
- 为每个记录的RN始终为1(因而总是等于)
- 两个记录之间的时间是10分钟。
我们期待的输出,看起来像下表:
| ID | TBL1_ID | TBL2_ID |
| '1' | '1' | '4' |
| '2' | '2' | '3' |
注1:如果“1”与“3” 2匹配,但随后”没关系'应与'4'匹配以符合约束,并且只要T1.MATCH_CRITERIA在T2.MATCH_CRITERIA的10分钟内。注2:我们从TBL1插入了100万条记录,另有100万条记录从TBL2插入。因此,使用PL/SQL进行顺序插入是不可接受的,除非它可以运行得非常快(少于15分钟)。
注3:不匹配的数据应该被消除。不平衡的数据也是预期的。
注4:我们不限于只执行1个查询。一系列有限的查询将会做。
发生什么情况,如果有在T1行不能在T2(反之亦然)行相匹配?你是否消除了这些数据?或者你是否希望最终得到'TBL1_ID'或'TBL2_ID'为NULL的输出? –
顺便说一下,您的测试数据在格式掩码中使用了'MM'两次。第二次你的意思是“MI”。这是一个常见的错误。 – APC
@JustinCave,消除数据。 – John