简体   繁体   中英

How to get delta records using pure SQL?

I have two tables T_Person and T_Person_New in Oracle SQL.

在此处输入图片说明

For ease, lets take Name as the unique identifier of both tables.

Can i Compare both tables to get the delta records using an SQL query?

The delta records should consist of the following condition:

  1. If it is a change in an existing record. Ie a change in DOB / Gender / Name
  2. If its a new record.

Thanks.

We can try using an EXISTS clause here:

SELECT ID, Name, DOB, Gender
FROM T_Person_New t1
WHERE NOT EXISTS (SELECT 1 FROM T_Person t2
                  WHERE t1.Name = t2.Name AND t1.DOB = t2.DOB AND t1.Gender = t2.Gender);

The logic here is to return every new record for which we cannot find an exactly matching record in the original table. This covers the case that the person already exists, but one or more of the fields have changed. And it also covers the case where the person is completely new, and did not even exist previously.

I have added one more record each in your sample data for old (t_person) and new (t_person_new) tables to cover for missing records from either tables.

I assume that id column is primary key in both tables (it's not clear from you description although you did mention name is unique).

old table sample data

insert into t_person values (1, 'Tom', '2000-01-01', 'M');
insert into t_person values (2, 'Gary', '2000-01-01', 'M');
insert into t_person values (3, 'Pam', '2000-01-01', 'F');
insert into t_person values (4, 'Hans', '2000-01-01', 'M');

new table sample data

insert into t_person_new values (1, 'Tom', '2000-01-01', 'M');
insert into t_person_new values (2, 'Gary', '2001-01-01', 'F');
insert into t_person_new values (3, 'Pamela', '2000-01-01', 'F');
insert into t_person_new values (5, 'Jane', '2000-01-02', 'F');

Here is a query that could show you all possible differences. I have done it only on name column, you can expand it for all columns.

select case when t.id is null then 'NEW: MISSING-FROM-OLD' 
            else case when tn.id is null then 'DELETED: MISSING-FROM-NEW' 
                      else 'EXISTS-IN-BOTH' 
                 end 
       end record_type    
       ,case when tn.name is null then 'MISSING-FROM-NEW, VALUE-IN-OLD (' + t.name + ')'
        else case when t.name is null then 'MISSING-FROM-OLD, VALUE-IN-NEW (' + tn.name + ')'
             else case when t.name = tn.name then 'SAME-IN-BOTH (' + t.name +')'
                  else 'CHANGED, VALUE-IN-OLD (' + t.name + '), VALUE-IN-NEW (' + tn.name +')' 
                 end 
            end 
       end name_state       
from t_person_new tn
full outer join t_person t on tn.id = t.id

Note: for Oracle you will have to use '||' instead of '+' to concatenate. I used '+' as I have SQL Server

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM