Oracle объединить в столбце с несколькими значениями - PullRequest
0 голосов
/ 12 марта 2020

У меня есть две таблицы в oracle базе данных

"persons" with columns (personid, lastname, firstname, address, city)
"person_details" with columns (id, personid, mobileno)

и таблица слияния

"merge_test" with columns (personid, detail_id, lastname, firstname, address, city, mobileno)

, и я использую следующую инструкцию слияния

merge into merge_test
using ( select p.personid personid,
            d.id detailid,
            p.firstname firstname,
            p.lastname lastname,
            p.address address,
            p.city city,
            d.mobileno mobileno
        from persons p
            left outer join person_details d
            on p.personid = d.personid ) source
on ( 
  merge_test.personid = source.personid
  and nvl(merge_test.detail_id, nvl(source.detailid, 0)) = nvl(source.detailid, 0)
)
WHEN MATCHED THEN
  UPDATE SET 
    merge_test.firstname = source.firstname,
    merge_test.lastname = source.lastname,
    merge_test.address = source.address,
    merge_test.city = source.city,
    merge_test.mobileno = source.mobileno
WHEN NOT MATCHED THEN
  INSERT (personid, detail_id, lastname, firstname, address, city, mobileno)
  values (source.personid, source.detailid, source.lastname, source.firstname, source.address, source.city, source.mobileno);

здесь merge_test.detail_id изначально будет нулевым и может получить несколько значений для person.personid (несколько строк для одного merge_test.person_id), а оператор слияния будет выполняться каждый час.

Я хочу объединить в таких способ, которым значение merge_test.detail_id обновляется, если обновляется значение source.detailid и вставляется новая строка для нескольких строк source.detailid.

Редактировать 13-03-2020

Приведенный выше запрос будет выполняться каждый час, и merge_test будет обновляться с использованием запроса на слияние.

для таблицы персон с такими данными, как

personid, lastname, firstname, address, city
1, 'lname', 'fname', 'add', 'city'
2, 'lname', 'fname', 'add', 'city'
3, 'lname', 'fname', 'add', 'city'

для таблицы person_details с данными, такими как

id, personid, mobileno
1, 1, 'mobileno'
2, 1, 'mobileno'
3, 2, 'mobileno'

приведет к таблице merge_test, как показано ниже

personid, detail_id, lastname, firstname, address, city, mobileno
1, 1, 'lname', 'fname', 'add', 'city', 'mobileno'
1, 2, 'lname', 'fname', 'add', 'city', 'mobileno'
2, 3, 'lname', 'fname', 'add', 'city', 'mobileno'
3, null, 'lname', 'fname', 'add', 'city', 'mobileno'

выше, данные генерируются с помощью оператора select и левого внешнего соединения

, когда таблица person_detail обновляется ниже detais

id, personid, mobileno
1, 1, 'mobileno'
2, 1, 'mobileno'
3, 1, 'mobileno'
4, 3, 'mobileno'

таблица тестирования слияния должна быть обновлена ​​как

personid, detail_id, lastname, firstname, address, city, mobileno
1, 1, 'lname', 'fname', 'add', 'city', 'mobileno'
1, 2, 'lname', 'fname', 'add', 'city', 'mobileno'
1, 3, 'lname', 'fname', 'add', 'city', 'mobileno'
2, null, 'lname', 'fname', 'add', 'city', 'mobileno'
3, 4, 'lname', 'fname', 'add', 'city', 'mobileno'

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

1 Ответ

0 голосов
/ 12 марта 2020

Обновленный ответ

После удаления у вас будет обновление для установки на ноль записей, в которых отсутствуют записи в таблице person_detail в таблице MERGE_TEST ..

Просто чтобы быть уверенным, что промежуточный ответ будет иметь следующие значения

personid, detail_id, lastname, firstname, address, city, mobileno
1, 1, 'lname', 'fname', 'add', 'city', 'mobileno'
1, 2, 'lname', 'fname', 'add', 'city', 'mobileno'
2, 3, 'lname', 'fname', 'add', 'city', 'mobileno'
3, null, 'lname', 'fname', 'add', 'city', null /*This should be null?*/

Я полагаю, что вы хотите потерять nvl logi c в предложении on и включить оператор delete после MERGE, как показано ниже на случаи, о которых вы говорили

(ваш запрос на слияние);

DELETE
  FROM merge_test a
 WHERE a.detail_id is null
   AND EXISTS (select 1 /* This block checks if we have a not_null details_id for the person_id and if so then delete the NULL entry*/
                 FROM merge_Test b
                WHERE a.person_id=b.person_id
                  AND a.detail_id=b.detail_id
              );

 UPDATE merge_test a
    SET a.detail_id=NULL
  WHERE NOT EXISTS (select 1 
                      from person_details b
                     where b.id=a.person_id);
...