Как получить дельта-записи, используя чистый SQL? - PullRequest
0 голосов
/ 21 марта 2019

У меня есть две таблицы T_Person и T_Person_New в Oracle SQL.

enter image description here

Для простоты давайте возьмем Имя в качестве уникальногоидентификатор обеих таблиц.

Можно ли сравнить обе таблицы, чтобы получить дельта-записи с использованием SQL-запроса?

Дельта-записи должны состоять из следующего условия:

  1. Если это изменение в существующей записи.Т.е. изменение в DOB / Gender / Name
  2. Если это новая запись.

Спасибо.

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Мы можем попробовать использовать предложение EXISTS здесь:

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);

Логика здесь в том, чтобы возвращать каждую новую запись, для которой не может найти точно совпадающую запись в исходной таблице. Это касается случая, когда человек уже существует, но одно или несколько полей изменились. И это также относится к случаю, когда человек совершенно новый, и даже не существовал ранее.

0 голосов
/ 21 марта 2019

Я добавил еще одну запись в ваши примеры данных для старых (t_person) и новых (t_person_new) таблиц, чтобы покрыть отсутствующие записи в обеих таблицах.

Я предполагаю, что столбец id является первичным ключом в обеих таблицах (из вашего описания не ясно, хотя вы упомянули имя уникальное).

старые данные таблицы

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');

новый образец данных таблицы

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');

Вот запрос, который может показать вам все возможные различия. Я сделал это только для столбца имени, вы можете расширить его для всех столбцов.

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

Примечание: для Oracle вы должны будете использовать '||' вместо «+» для объединения. Я использовал '+', поскольку у меня есть SQL Server

...