Объединение записей в таблице и обновление связанных таблиц - PullRequest
0 голосов
/ 20 сентября 2018

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

Таблица: пользователи

UserID    Username    FirstName    LastName
1         Main        John         Doe
2         Duplicate   John         Doo

Таблица: записи1

RecordID  RecordName      CreatedUserID   UpdatedUserID
1         Test record 1   1               2
2         Test record 2   2               null
3         Test record 3   2               null

CreatedUserID и updatedUserID являются внешними столбцами Users.UserID.
ИтакВ настоящее время, если я хочу объединить пользователей 1 и 2, я бы сделал это с помощью следующих операторов SQL:

UPDATE Records1 SET UpdatedUserID = 1 WHERE UpdatedUserID = 2
UPDATE Records1 SET CreatedUserID = 1 WHERE CreatedUserID = 2
DELETE FROM Users WHERE UserID = 2

Это всего лишь примерное подмножество, но на самом деле существует множество таблиц связанных записей, для которых ядолжны добавить дополнительные операторы SQL-Update.

Я знаю, что, возможно, мне здесь повезло, но, возможно, есть способ выполнить вышесказанное (обновить все связанные таблицы в пакете и удалить «дублирующую» запись) вместо обновления каждого внешнего поля икаждая связанная таблица вручную.Таблица users - это, по сути, базовая таблица, которая связывается со всеми остальными таблицами, поэтому создание отдельных операторов для каждой таблицы довольно громоздко, поэтому, если имеется ярлык, это было бы здорово.

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Поскольку процесс идентификации дублирующих учетных записей будет ручным, тогда (как правило) будут обрабатываться пары учетных записей.(Я предполагаю, что Инспектор не может пометить 15 учетных записей пользователей как дубликаты в вашем пользовательском интерфейсе и отправить весь лот для обработки.)

Хранимая процедура, подобная следующей, может быть хорошим началом:

create procedure MergeUsers
  @RetainedUserId Int, -- UserId   that is being kept.
  @VictimUserId Int -- UserId   that is to be removed.

as
  begin

  -- Validate the input.
  --   Optional, but you may want some reality checks.
  --   (Usernames are probably unique already, eh?)
  declare @UsernameMatch as Int, @FirstNameMatch as Int, @LastNameMatch as Int, @EmailMatch as Int;
  select
    @UsernameMatch = case when R.Username = V.Username then 1 else 0 end,
    @FirstNameMatch = case when R.FirstName = V.FirstName then 1 else 0 end,
    @LastNameMatch = case when R.LastName = V.LastName then 1 else 0 end,
    @EmailMatch = case when R.Email= V.Emailthen 1 else 0 end
    from Users as R inner join
      Users as V on V.UserId = @VictimUserId and R.UserId = @RetainedUserId;
  if @UsernameMatch + @FirstNameMatch + @LastNameMatch + @EmailMatch < 2
    begin
    -- The following message should be enhanced to provide a better clue as to which user
    --   accounts are being processed and what did or didn't match.
    RaIsError( 'MergeUsers: The two user accounts should have something in common.', 25, 42 );
    return;
    end;

  -- Update all of the related tables.
  --   Using a single pass through each table and updating all of the appropriate columns may improve performance.
  --   The   case   expression will only alter the values which reference the victim user account.
  update Records1
    set
      CreatedUserId = case when CreatedUserId  = @VictimId then @RetainedUserId else CreatedUserId end,
      UpdatedUserId = case when UpdatedUserId = @VictimId then @RetainedUserId else UpdatedUserId end
    where CreatedUserId = @VictimUserId or UpdatedUserId = @VictimUserId;

  update Records2
    set ...
    where ...;

  -- Houseclean   Users .
  delete from Users
    where UserId = @VictimUserId;

  end;

NB : в качестве упражнения добавляется try / catch и транзакция в SP, чтобы гарантировать, что объединение является операцией "все или ничего".

0 голосов
/ 21 сентября 2018

это полезно ??

    Create Table Users(Id int, UserName varchar(10),FirstName varchar(10), LastName Varchar(10))
    Create Table Records1(RecordID int,  RecordName varchar(20), CreatedUserID int,   UpdatedUserID int)


    INSERT INTO Users
    SELECT 1,'Main','John','Doe' Union All
    SELECT 2,'Duplicate','John','Doo' Union All

    SELECT 3,'Main3','ABC','MPN' Union All
    SELECT 4,'Duplicate','ABC','MPT' 


    Insert into Records1
    SELECT 1,'Test record 1',1,2    Union All
    SELECT 2,'Test record 2',2,null Union All
    SELECT 3,'Test record 3',2,null Union All

    SELECT 1,'Test record 1',3,4    Union All
    SELECT 2,'Test record 2',4,null Union All
    SELECT 3,'Test record 3',4,null 

    Select u1.Id as CreatedUserID,U2.id as UpdatedUserID
    Into #tmpUsers 
    from Users u1
    JOIN Users u2 
    --This Conidition Should be changed based on the criteria for identifying Duplicates
    on u1.FirstName=u2.FirstName and U2.UserName='Duplicate'
    Where u1.UserName<>'Duplicate'


    Update r
    Set r.UpdatedUserID=u.CreatedUserID
    From Records1 r
    JOIN #tmpUsers u on r.CreatedUserID=u.CreatedUserID

    Update r
    Set r.CreatedUserID=u.CreatedUserID
    From Records1 r
    JOIN #tmpUsers u on r.CreatedUserID=u.UpdatedUserID

    Delete from Users Where UserName='Duplicate'

    Select * from Users
    Select * from Records1


    Drop Table #tmpUsers
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...