2014-12-31 5 views
1

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

Хотя есть куча полей и таблиц участвуют, для простоты скажем есть только одна таблица Person, которая выглядит следующим образом:

PersonID, FirstName, LastName, Organization, Email 
1, Rick, Smith, Company A, [email protected] 
2, Richard, Smith, Company A, [email protected] 
3, Richie, Smith, Company A, [email protected] 
4, Jonathan, Doe, Company X, [email protected] 
5, John, Doe, Company X, [email protected] 
6, Michael, Johnson, Company X, [email protected] 

то, что я хотел бы сделать, это найти всех людей, которые могут быть продублированы на основании которых из них имеют те же поля равны. Например, если я хочу найти всех людей, у которых есть такое же LastName + Email + Organization, то я бы объединил первые 3 записи в один и запишу 5 в 4. У меня есть сохраненный процесс, чтобы сделать это один за другим:

exec mergePerson 2, 1 
exec mergePerson 3, 1 
exec mergePerson 5, 4 

[править]: в этом случае полученный результат будет ниже (это упрощается: хранимая процедура заботится о интеллектуально слияния дюжины один-ко-многим таблицам в фоновом режиме, такие как человеко-заказов , контактные линзы и т. д.).

1, Rick, Smith, Company A, [email protected] 
4, Jonathan, Doe, Company X, [email protected] 
6, Michael, Johnson, Company X, [email protected] 

но как это сделать оптом? Я думаю, мне нужно как-то сделать цикл while, но не уверен, как его настроить. Я видел несколько удачных способов удалить несколько записей в CTOs и разделах разделов stackoverflow usine, но это немного над моей головой, и я не знаю, могут ли они применяться здесь

Не имеет значения, в каком порядке слияние выполняется в том или ином источнике и цели. То есть, это будет работать тоже:

exec mergePerson 2, 3 
exec mergePerson 3, 1 
exec mergePerson 4, 5 

Я использую SQL Server 2008 R2

+1

Когда вы говорите о слиянии, вы имеете в виду обновление/вставку или просто фильтрацию дубликатов? –

+0

Хороший вопрос. Слияние хранимой proc удаляет дубликаты после слияния (имеется куча связанной информации в других таблицах, таких как заказы, сделанные человеком, контактные заметки и т. Д.). В первом примере после слияния у вас будет всего 3 записи: 1, 4, 6. Этот сохраненный процесс уже написан. – user46372

+0

ОК, позвольте мне обновить свой ответ соответственно. –

ответ

1

Попробуйте это:

;with cte as 
(select *, row_number() over (partition by lastname, organization,email order by id) rn 
from tbl) 

delete from cte 
where rn <> 1 

КТР в основном номера записи на основе ваших критериев для обнаружения дубликаты. Затем оператор delete удаляет оскорбительные записи из таблицы, за исключением первого вхождения записи.

Demo

+0

Отлично, но я думаю, что ему нужно выполнить хранимую процедуру. Существует тонна вещей, которые продолжаются в процедуре.Этот хранимый proc определяет, как наилучшим образом объединить записи без потери информации, тянет таблицы «один ко многим» (персонализированные заказы, персонализированные контакты и т. Д.) И сглаживает их разумно. – user46372

+1

А, я вижу. Не могли бы вы поделиться кодом для хранимой процедуры? –

+0

О, человек, это более 100 строк. В основном это обновление таблиц один-ко-многим. Например, на самом деле есть таблица для всех адресов электронной почты, связанных с Person, поэтому код должен объединить их из sourcePerson в targetPerson без создания дубликатов. Ваше решение кажется очень близким, хотя. В вашем примере будет ли способ выполнить команду для всех строк, где rn <> 1? Это решило бы это, я думаю – user46372

0

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

SELECT Min(Person_id), First_name, (Last_name + " " + Organization + " " + " " + email) AS cc_string 
FROm table1 
GROUP BY first_name,(Last_name + " " + Organization + " " + " " + email) 
+0

О, это интересно. Это дало бы мне PersonIDs 1, 4 и 6, но мне нужны другие персональные идентификаторы для выполнения сгенерированного слияния proc. Как я их получу? – user46372

+0

Хорошая точка - если у вас только два дубликата, вы можете сделать то же самое, что и выше, но выберите макс. Я бы предположил, что из вашего описания у вас более двух дубликатов на человека. –

0

Вы смотрите на курсоры? Курсор позволит вам выполнить запрос выбора, а затем выполнить некоторые процедуры/шаги для каждой строки, возвращаемой запросом. http://msdn.microsoft.com/en-us/library/ms180169.aspx

+0

Да, похоже, мне придется читать курсоры. У меня возникают проблемы с тем, что будет выглядеть так, как будет выглядеть инструкция select, которую я использую с помощью курсора. – user46372

+0

В основном будет курсор, который будет отображать все строки, показанные выше в вашем вопросе, а затем для каждой возвращаемой строки, которую вы хотите сделать другой курсор, который будет искать все строки, которые являются дубликатами текущего, возвращаемого курсором. Если хотя бы один возвращается, выполните задачу, если строки не вернулись, перейдите к следующей строке в первом курсоре. – Stc5097