Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
Как лучше организовать процедуру поиска дубликатов в таблице, выполнение с ними некоторых действий и удаление?
8 янв 10, 17:33    [8157639]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
Glory
Member

Откуда:
Сообщений: 104760
https://www.sql.ru/forum/actualthread.aspx?tid=127456
8 янв 10, 17:42    [8157670]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
Таблица пользователей Users с полями ID, First Name, Second Name, Last Name.
Есть таблица заказов пользователей UserOrders, в котором есть завязка на пользователя UserID.
Необходимо организовать процедуру с поиском дупликатов для их удаления и изменения в таблице UserOrders ID дупликата на начального пользователя.
8 янв 10, 17:47    [8157696]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
Glory
Member

Откуда:
Сообщений: 104760
iperry
Таблица пользователей Users с полями ID, First Name, Second Name, Last Name.
Есть таблица заказов пользователей UserOrders, в котором есть завязка на пользователя UserID.
Необходимо организовать процедуру с поиском дупликатов для их удаления и изменения в таблице UserOrders ID дупликата на начального пользователя.

Если у вас дубликаты в таблице UserOrders, то зачем вы рассказываете про таблицу Users ?
И что такое "начальный пользователь" ?
8 янв 10, 17:50    [8157706]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
Glory,

Дубликат создается в таблице Users и затем создается запись с его заказом в таблице UserOrders.
Необходимо удалить дубликат из таблицы UsersБ а созданные им заказы перензанчить на оригинальную запись.

Пример
Users
ID FName SName LName
1 Иван Иваныч Иванов
2 Петр Петрович Петров
3 Иван Иваныч Иванов

UserOrders
ID UserID ...
1 1 ----
2 2 ----
3 1 -----
4 3 ------

Желаемый результат после выполнения процедуры
Users
ID FName SName LName
1 Иван Иваныч Иванов
2 Петр Петрович Петров

UserOrders
ID UserID ...
1 1 ----
2 2 ----
3 1 -----
4 1 ------
8 янв 10, 17:56    [8157726]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iperry,

1. про версию сервера говорили или я что-то пропустил?
2. как определить, что две записи относятся к одной и той же сущности? По тексту ФИО? А если в записи ID=3 было бы "Иван Иванович Иванов"?
И вообще, разве можно полагаться на посимвольное различие двух строк?
Кстати, что мешает двум реальным людям иметь одинаковые фамилию, имя и отчество?
Два Ивана Ивановича Иванова быть не может, что ли?
3. IMHO, правильным было бы создать и заполнть таблицу, связывающую ID записей, которые надо оставить, и записи-дубликаты.
Причём эту таблицу надо дать заполнить самим пользователям через специально созданный клиентский интерфейс.
С такой таблицей задача становится тривиальной.
8 янв 10, 18:12    [8157770]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
iap,
ms sql server 2005
данные примеры таблиц - всего лишь примерное описание задачи. На самом деле таблицы громоздкие и определение дубликата идет по сопоставление полей типа ИНН. И дело не в правильности структуры таблиц или интерфейса: приходится работать с тем, что есть сейчас.
Поэтому предложите пожалуйста варианты, по существующей системе.
8 янв 10, 19:53    [8158129]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iperry,

например:
UPDATE O
SET O.UserID=(SELECT MIN(U2.ID) FROM Users U1 JOIN Users U2 ON U1.FName=U2.FName AND U1.SName=U2.SName AND U1.LName=U2.LName WHERE U1.ID=O.UserID)
FROM UserOrders O;

DELETE U
FROM Users U
WHERE U.ID NOT IN (SELECT MIN(UU.ID) FROM Users UU GROUP BY UU.FName, UU.SName, UU.LName);
Есть ещё десяток способов
8 янв 10, 21:46    [8158443]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
iap
iperry,

например:
UPDATE O
SET O.UserID=(SELECT MIN(U2.ID) FROM Users U1 JOIN Users U2 ON U1.FName=U2.FName AND U1.SName=U2.SName AND U1.LName=U2.LName WHERE U1.ID=O.UserID)
FROM UserOrders O;

DELETE U
FROM Users U
WHERE U.ID NOT IN (SELECT MIN(UU.ID) FROM Users UU GROUP BY UU.FName, UU.SName, UU.LName);
Есть ещё десяток способов


Таблица UserOrders очень большая, намного больше Users, апдейтить каждую ее строчку долго.
9 янв 10, 08:13    [8159389]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
А так:
UPDATE O
SET O.UserID=U.ID
FROM UserOrders O
CROSS APPLY
(
 SELECT MIN(U2.ID)
 FROM Users U1 JOIN Users U2
   ON U1.FName=U2.FName AND U1.SName=U2.SName AND U1.LName=U2.LName
 WHERE U1.ID=O.UserID
 HAVING COUNT(*)>1
) U(ID);
?
9 янв 10, 12:46    [8159593]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
iperry
Member

Откуда:
Сообщений: 17
iap
А так:
UPDATE O
SET O.UserID=U.ID
FROM UserOrders O
CROSS APPLY
(
 SELECT MIN(U2.ID)
 FROM Users U1 JOIN Users U2
   ON U1.FName=U2.FName AND U1.SName=U2.SName AND U1.LName=U2.LName
 WHERE U1.ID=O.UserID
 HAVING COUNT(*)>1
) U(ID);
?


На самом деле этот вариант тоже не намного увеличивает скорость работы.
Вариант с проходом по таблице Users и затем апдейт по найденным ID таблицы UserOrders выглядит перспективнее
9 янв 10, 14:28    [8159798]     Ответить | Цитировать Сообщить модератору
 Re: поиск дупликатов  [new]
aleks2
Guest
iperry
На самом деле этот вариант тоже не намного увеличивает скорость работы.
Вариант с проходом по таблице Users и затем апдейт по найденным ID таблицы UserOrders выглядит перспективнее


По-старинке - оно надежнее...
UPDATE O
SET O.UserID=X.NewID
FROM UserOrders O
inner join
(
	SELECT U1.ID, MIN(U2.ID) NewID
	FROM 
	Users U1 INNER JOIN Users U2
	ON U1.FName=U2.FName AND U1.SName=U2.SName AND U1.LName=U2.LName AND U1.ID>U2.ID
	GROUP BY U1.ID
) X
ON X.ID=O.UserID
9 янв 10, 16:42    [8160047]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить