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

Откуда:
Сообщений: 11
Добрый день.

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

Есть 2 таблицы: Account и Contact.

В таблице компаний (Account) есть дублирующиеся записи (более 200 000) типа Компания 1 и Компания 2.

Компания 1 - нормальная запись, Компания 2 - дубль с тем же именем.

При этом в таблице компаний среди прочих есть поля Acoount.ID, Account.Name и Account.PrimaryContactID (пишу с префиксом имени таблицы).

По полю Account.PrimaryContactID запись Компания 1 ссылается на запись в таблице Contact, на ID основного контакта, а эта запись из таблицы Contact по полю AccountID ссылается на запись Компания 2, а должна на Компанию 1.

Нужно в таблицу Contact в поле AccountID подставить значение ID Компании 1 вместо ID Компании 2. Это нужно сделать по всем записям, где есть дубли.

Потом дубли удалить.
11 дек 11, 23:12    [11746131]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
А в чем проблема?
11 дек 11, 23:18    [11746151]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Проблема в том, что мне неясно как сделать UPDATE таблицы Contact по всем записям, WHERE contact.id = account.primarycontactid and accountid=account.id - SQL не может связать множественные результаты, а как выделить точный единичный соответствующий ID неясно.

после WHERE должно быть выражение, которое позволит определить запись, но я не могу понять как его правильно составить.

Сергей, а Вы как бы сделали?
12 дек 11, 00:43    [11746360]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Смысл проблемы - что я не могу просто удалить дубли Компаний 2 - на них ссылаются существующие записи контактов.

Если просто почистить поля Contact.accountID - удалить дубли смогу, но потеряется связь.
А мне нужно чтобы в поле Contact.accountID вместо ID Компании 2 был ID Компании 1.

Но ID же все разные, как их правильно выбрать в UPDATE, чтобы запрос работал я не знаю.
12 дек 11, 00:51    [11746377]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Например, если мне нужно, чтобы контакт ссылался на Компанию 1, ID которой ХХХ, я могу сделать запрос:

UPDATE contact
SET accountid = 'XXX'
WHERE ID = (SELECT PrimaryContactID from Account where id = 'XXX');

Но мне нужно, чтобы вместо ХХХ было буквально "тот ID Компании, PrimaryContactID которой ссылается на текущий контакт" - это величина переменная и мне тут не хватает знаний.
12 дек 11, 01:02    [11746430]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
Если честно, то не совсем "догоняю" связь и задачу, но
UPDATE contact
SET accountid = 'XXX'
from contact dest inner join (select ... from contact where ) src on .. = ...
WHERE ....
это?
12 дек 11, 01:44    [11746551]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Благодарю за ответ, SIMPLicity, я попробую.

Но дело в том, что я не могу писать SET accountid = 'XXX'. XXX - это ID типа E637F186-B716-4D48-80CB-01254D1AA6C6 - теоретически для каждого Контакта я могу его выяснить, но таких контактов около 250 000 - вручную каждый раз узнавать ID нереально. Также как и 250 000 раз запускать запрос.

Мне нужно что-то вроде логики: "выбрать очередную запись из таблицы Contact, выбрать запись из таблицы Account, у которой PrimarContactID = Contact.id (текущей записи Контакта), и для текущей записи контакта в поле AccountID записать значение ID выбранной записи из таблицы Account" - для всех записей Contact.
12 дек 11, 09:57    [11747084]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
проходящий.
Guest
Denis Oya
Благодарю за ответ, SIMPLicity, я попробую.

Но дело в том, что я не могу писать SET accountid = 'XXX'. XXX - это ID типа E637F186-B716-4D48-80CB-01254D1AA6C6 - теоретически для каждого Контакта я могу его выяснить, но таких контактов около 250 000 - вручную каждый раз узнавать ID нереально. Также как и 250 000 раз запускать запрос.

Мне нужно что-то вроде логики: "выбрать очередную запись из таблицы Contact, выбрать запись из таблицы Account, у которой PrimarContactID = Contact.id (текущей записи Контакта), и для текущей записи контакта в поле AccountID записать значение ID выбранной записи из таблицы Account" - для всех записей Contact.
Вот с последнего предложения топик и надо было начинать, а не рассказывать свое решение через позаписный цикл. Команда Update может обновлять сразу много записей, ей только нужно указать в каких записяз и что обновлять.
12 дек 11, 10:12    [11747139]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Denis Oya,

а как у Вас называется таблица счетов компании?

И главное: мы увидим скрипт создания таблиц и заполнения их тестовыми данными?
Иначе отвечать нет смысла.

P.S. Не забудьте указать версию сервера!
12 дек 11, 10:18    [11747164]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
проходящий.
Команда Update может обновлять сразу много записей, ей только нужно указать в каких записяз и что обновлять.


Супер! А как это сделать в моем случае?

iap,

У меня таблицы счетов нет, есть таблица компаний = Account и таблица Контактов = Contact

Сервер Ms SQL 2008. Таблицы мной не создавались, скрипт создания предоставить к сожалению не могу.
12 дек 11, 12:24    [11748179]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
Denis Oya
есть поля Acoount.ID, Account.Name и Account.PrimaryContactID
Очень напоминает структуру CRM Sage SalesLogix. Там в клиенте есть механизм удаления дублей.
А через SQL надо еще смотреть в таблице AccountSummary, Opportunity... Навскидку не помню.
12 дек 11, 12:40    [11748328]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Denis Oya
проходящий.
Команда Update может обновлять сразу много записей, ей только нужно указать в каких записяз и что обновлять.


Супер! А как это сделать в моем случае?

iap,

У меня таблицы счетов нет, есть таблица компаний = Account и таблица Контактов = Contact

Сервер Ms SQL 2008. Таблицы мной не создавались, скрипт создания предоставить к сожалению не могу.
Просто Account - это "счёт" по-английски. Никак не "компания"...

Что касается скрипта, то в SQL Server Management Studio его можно получить для любого объекта в Object Explorer
12 дек 11, 13:09    [11748672]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

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

Что касается скрипта, то в SQL Server Management Studio его можно получить для любого объекта в Object Explorer


Увидел, сделал, приложил. Для таблицы Компаний

К сообщению приложен файл (account.sql - 6Kb) cкачать
12 дек 11, 13:55    [11749327]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
И для таблицы Контактов

К сообщению приложен файл (Contact.sql - 5Kb) cкачать
12 дек 11, 13:56    [11749335]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Спасибо всем, нашел решение с использованием курсора на transact sql - не самое элегантное и выполняется больше 20 часов, но работает:

DECLARE @CID nvarchar(250)

DECLARE curs CURSOR
FOR
(SELECT id FROM Contact WHERE AccountID in
(SELECT id FROM Account WHERE code is null))

OPEN curs

WHILE 1=1
begin
FETCH next FROM curs INTO @CID
if @@fetch_status<>0 break
UPDATE Contact
SET AccountID = (SELECT ID FROM Account
WHERE PrimaryContactID = @CID)
WHERE id = @CID
end
CLOSE curs
DEALLOCATE curs
14 дек 11, 01:24    [11761246]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Denis Oya
нашел решение с использованием курсора на transact sql - не самое элегантное
Не растите в себе говно кодера. Тем более процедурномыслие.
Пьяница, в первую очередь разрешает себе выпить. "Ну ещё разок и брошу."

Потратили бы час-два на "без курсора". Глядишь, а завтра это займёт 3 минуты ... 3 секунды ...
14 дек 11, 05:07    [11761386]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
Mnior
Denis Oya
нашел решение с использованием курсора на transact sql - не самое элегантное
Не растите в себе говно кодера. Тем более процедурномыслие.
Пьяница, в первую очередь разрешает себе выпить. "Ну ещё разок и брошу."

Потратили бы час-два на "без курсора". Глядишь, а завтра это займёт 3 минуты ... 3 секунды ...

Выкидывая флуд, я +1 за Mnior.
Попробуйте без курсора.
PS хотя, если Вы с SQL случайно - то забейте нах - "сойдёт и так" (с) ХЗ_какой_фильмнепомню)
14 дек 11, 10:15    [11761908]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Я потому и обратился, что без Курсора не нашел решения - Ваши варианты?
14 дек 11, 12:31    [11763008]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
cross aplly
14 дек 11, 12:36    [11763060]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Lasa
Member

Откуда: Canada
Сообщений: 81
Если я правильно поняла задачу, то Update очень легкий, но может это я что-то не то поняла?
Это тестетовые данные
USE [Test]
GO
/****** Object:  Table [dbo].[tbl_Contact]    Script Date: 12/14/2011 15:05:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tbl_Contact](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[AccountID] [int] NOT NULL,
	[Name] [nvarchar](250) NOT NULL,
 CONSTRAINT [PK_tbl_Contact] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[tbl_Contact] ON
INSERT [dbo].[tbl_Contact] ([ID], [AccountID], [Name]) VALUES (1, 1, N'Contact1')
INSERT [dbo].[tbl_Contact] ([ID], [AccountID], [Name]) VALUES (2, 2, N'Contact2')
INSERT [dbo].[tbl_Contact] ([ID], [AccountID], [Name]) VALUES (3, 4, N'Contact3')
INSERT [dbo].[tbl_Contact] ([ID], [AccountID], [Name]) VALUES (4, 4, N'Contact4')
SET IDENTITY_INSERT [dbo].[tbl_Contact] OFF
/****** Object:  Table [dbo].[tbl_Account]    Script Date: 12/14/2011 15:05:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tbl_Account](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](250) NOT NULL,
	[PrimaryContactID] [int] NULL,
 CONSTRAINT [PK_tbl_Account] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[tbl_Account] ON
INSERT [dbo].[tbl_Account] ([ID], [Name], [PrimaryContactID]) VALUES (1, N'Account1', 1)
INSERT [dbo].[tbl_Account] ([ID], [Name], [PrimaryContactID]) VALUES (2, N'Account2', 2)
INSERT [dbo].[tbl_Account] ([ID], [Name], [PrimaryContactID]) VALUES (3, N'Account3', 3)
INSERT [dbo].[tbl_Account] ([ID], [Name], [PrimaryContactID]) VALUES (4, N'Account4', 4)
SET IDENTITY_INSERT [dbo].[tbl_Account] OFF


Update
UPDATE tbl_Contact 
SET tbl_Contact.AccountID = tbl_Account.ID
FROM dbo.tbl_Contact INNER JOIN
               dbo.tbl_Account ON dbo.tbl_Contact.ID = dbo.tbl_Account.PrimaryContactID
WHERE tbl_Contact.AccountID <> tbl_Account.ID  
15 дек 11, 03:08    [11768373]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дублей со связями  [new]
Denis Oya
Member

Откуда:
Сообщений: 11
Lasa, SIMPLisity - спасибо за помощь.
Особенно Lasa - похоже этот вариант работает и гораздо лучше.

Большое человеческое спасибо и огромный нечеловеческий респект!
16 дек 11, 15:30    [11778453]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить