SQL Merging Associated Records

Refresh

December 2018

Views

183 time

2

Let's say we have a database with a table that has many other associated tables. If you diagrammed the database, this would be the table at the center with many foreign key relationships spiraling out of it.

To make it more concrete, let's say the two records in this central table are Initech and Contoso. Initech and Contoso are both associated with many other records in associated tables like Employees, AccountingTransactions, etc. Let's say the two merged (Initech bought Contoso) and from a data standpoint, it really is as simple as merging all the records. What's the easiest way to take all of Contoso's related records, make them point to Initech and then delete Contoso?

UPDATE with CASCADE comes tantalizingly close, but it obviously can't work without turning off constraints and then turning them back on (yuck).

Is there a nice generic way to do this without hunting down every single linked table and migrating them one by one? This has to be a common requirement. It's come up in two places in this project and can be summed up with: Entity A needs to control everything Entity B current controls. How can I make it happen?

Before Merge:

Companies
ID Name
1  Contoso
2  Initech

Employees
ID Name CompanyId
1  Bob  1 
2  Ted  2

After Merge:

Companies
ID Name
2  Initech

Employees
ID Name CompanyId
1  Bob  2 
2  Ted  2

All my attempts at searching only turned up questions about merging separate databases... so sorry if this has been asked before.

3 answers

0

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

Один из способов могут быть реализация родительского рисунка на вашей центральную таблице (или абстрагировать в другую таблицу). Затем вы в конечном итоге с чем-то вроде

Companies 
ID ParentID Name 
1  2        Contoso 
2  null     Initech  

или же

Companies 
ID ParentID Name 
1  3        Contoso 
2  3        Initech  
3  null     MegaInitech

и все ваши запросы , которые объединяют на этой центральную Companiesтаблицу теперь проверяют удостоверение личности и ParentID;

SELECT * 
FROM Employees          
WHERE CompanyId IN (SELECT ID FROM Companies WHERE ID = @id OR ParentID = @ID)

Аннотация это далеко на вид или функции

CREATE FUNCTION fn_IsMemberOf
(
    @companyId INT,
    @parentId INT
)
RETURNS BIT
AS
BEGIN   
    DECLARE @result BIT = 0
    SELECT @result = 1 FROM Companies 
    WHERE ID = @companyId
        AND COALESCE(ParentID, ID) = @parentID
    RETURN @result
END

SELECT * 
FROM Employees          
WHERE fn_IsMemberOf(CompanyId, 1) = 1

(Не проверял это, но вы получите идею)

1

Этот запрос, скорее всего, от поставщика зависит, но в MySQL:

UPDATE Employees e, Cars c, OtherEntity o
  SET e.CompanyId = 2, c.CompanyId = 2, o.CompanyID = 2
  WHERE e.CompanyID = 1 OR c.CompanyId = 1 OR o.CompanyId = 1;
0

не Сжато, нет; не существует универсального способа сделать это.

Рассмотрите свою базу данных с таблицами компаниями, сотрудниками, отделами и AccountingTransactions.

Вам нужно удалить одну из записей компании (потому что после слияния, вы будете записывать только текущее положение дел).

Вы должны изменить записи сотрудников, чтобы изменить использующую компанию. Тем не менее, вполне возможно, что есть номер сотрудника N в обеих компаниях, и один из них (предположительно с Contoso) должен быть присвоен новый номер сотрудника.

Вы, вероятно, сталкиваетесь с проблемой, что отдел 1 в данном Conotoso является Engineering, но в Initech являются Финансы. Итак, вам нужно беспокоиться о том, как вы собираетесь отобразить номера отделов между двумя компаниями, а затем вы столкнулись с проблемой присвоения сотрудников Contoso для отделов Initech в.

Для исторических бухгалтерских операций, вы, вероятно, должны иметь исторические учетные записи Contoso в имени Contoso, в то время как некоторые (из последних) операций должны быть перенесены на имя Initech в. Так что, может быть, вы не будете удалять записи Contoso из таблицы компаний после того, как все, но вы не сможете использовать его, чтобы определить, какие новые записи.

Это лишь небольшая выборка из причин, почему такие отображения не могут быть легко автоматизированы.