2011-01-10 5 views
0

не был уверен в том, чтобы поместить это в программное обеспечение или здесь, так что я решил начать здесь я знаю, что это будет прямой ответ от вас SQL гениев ...SQL Query Help - удаление дубликатов

I есть таблица, она содержит контакты, которые я импортирую ежедневно. У меня будет интерфейс ASP.NET для взаимодействия с пользователем. Из этой таблицы я собираюсь отправить их всем почтовым отправителям, но только по одному на каждый адрес. Таким образом, мой конечный результат заключается в том, что пользователь вводит дату (которая соответствует импортированной дате), и им предоставляется результирующая сетка со всеми уникальными адресами, связанными с этой датой. Я только хочу отправить почтовое сообщение на этот адрес один раз - много раз мой первоначальный импортированный список будет содержать несколько компаний по тому же адресу.

Таблица: ContactTable Fielsd: ID, CompanyName, Адрес, Город, Район, Страна, Телефон

Я могу использовать SELECT DISTINCT положение, но мне нужны все данные, связанные с ним (название компании и т.д. .)

У меня более 262000 записей в этой таблице.

Если я выбираю дату выборки 1/10/2011, я получаю 2401 запись. SELECT DISTINCT Адрес с той же даты дает мне 2092 записи. Это выполнимо, я отправил бы этим 2092 людям почтовую программу.

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

Какой у меня лучший способ?

+0

Являются ли ваши адреса очищенными/стандартизованными, чтобы они были одинаковыми? Например, "123 Main St." против «123 Main Street», «St. Louis MO» и «Saint Louis MO» и т. д. –

+0

К сожалению, они не очищены на 100%. Мы получаем эти ежедневные списки от компании, и, честно говоря, это не всегда чистые данные. Мы знаем, что из-за этого произойдет некоторая ошибка, хотя есть ли какая-то настройка, которую я могу сделать для таблицы, прежде чем ее немного почистить? – RogueSpear00

+1

Вам нужна колонка ID в результатах? Похоже, что простой DISTINCT или GROUP BY будут работать, если вы удалили столбец идентификатора (например, SELECT CompanyName, Address, City, State, Zip, Phone FROM ContactTable GROUP BY CompanyName, Address, City, State, Zip, Phone). – Zachary

ответ

0

Я бы выбрать, а затем удалить, то дублирует это:

SELECT a.ID, a.PurgedID, a.CAMPAIGNTYPE, a.COMPANY, a.DBANAME, a.COADDRESS, a.COCITY, a.COSTATE, a.COZIP, a.FIRSTNAME1, a.DIALERPHONENUM, a.Purged FROM PurgeReportDetail a 
WHERE EXISTS (
    SELECT * FROM PurgeReportDetail b WHERE 
    b.COADDRESS = a.COADDRESS 
    AND b.COCITY = a.COCITY 
    AND b.COSTATE = a.COSTATE 
    AND b.COZIP = a.COZIP 
    AND b.id <> a.id 
    ) -- This clause will only include rows with duplicate columns noted 
AND a.ID IN (
    SELECT TOP 1 c.ID from PurgeReportDetail c 
    WHERE c.COADDRESS = a.COADDRESS 
    AND c.COCITY = a.COCITY 
    AND c.COSTATE = a.COSTATE 
    AND c.COZIP = a.COZIP 
    ORDER BY c.ID -- If you want the *newest* entry to be saved, add "DESC" here 
    ) -- This clause gets the top 1 ID value for each matching set 

или что-то в этом роде. Это сохранит первый идентификатор избыточного адреса, просто замените SELECT на DELETE, когда будете готовы.

EDIT: Конечно, это будет работать только на точках.

EDIT2: Если вы хотите только проверить, где вы не послали почтовые программы, вы должны присоединиться как к столу, отправленных почтовых программ из заданного диапазона дат

+0

Мэтью, я попытался использовать ваше решение, но это привело к ошибкам. Я не являюсь SQL-гуру, но Query постоянно менялся. См. Пример: – RogueSpear00

+0

SELECT ID, PurgedID, CAMPAIGNTYPE, COMPANY, DBANAME, COADDRESS, COCITY, COSTATE, COZIP, FIRSTNAME1, DIALERPHONENUM, очищенный FROM dbo.PurgeReportDetail AS WHERE (ID IN (SELECT TOP (1) C.ID FROM dbo .PurgeReportDetail AS B WHERE (C.COADDRESS = A.COADDRESS) AND (C.COCITY = A.COCITY) AND (C.COSTATE = A.COSTATE) AND (C.COZIP = A.COZIP) ORDER BY C.ID)) И СУЩЕСТВУЮТ (ИДЕНТИФИКАТОР ВЫБОРОВ, ПОВЫШЕННЫЙ ИДЕНТИФИКАТОР, КАМПАНИЯ, КОМПАНИИ, БЛАНК, КОАДДРЕС, КОКТИЮ, КОСТЕЙ, КОЗИП, ПЕРВЫЙ ИМЕНА1, ДИАЛЕРФОНЕНУМ, Очищенный ОТ dbo.PurgeReportDetail AS – RogueSpear00

+0

c ГДЕ (COADDRESS = A.COADDRESS) AND (COCITY = A. COCITY) И (COSTATE = A.COSTATE) И (COZIP = A.COZIP) И (ID <> ID)) – RogueSpear00

1

Я бы начал с создания таблицы для поиска отправленных почтовых отправлений.

ID | DateSent 
------------- 

Каждый раз, когда вы отправляете почтовую программу, которую вы собираетесь вставить идентификатор, и DateTime в него, таким образом, когда вы идете, чтобы вытащить мейлеры вы можете посмотреть на эту таблицу, чтобы увидеть, если почтовая программа имеет был отправлен в течение любых указанных вами сроков рассылки. Вы можете расширить это, если у вас есть несколько типов почтовых отправителей для включения типа почтовой программы.

Plain Old SQL

SELECT a.ID, a.CompanyName, b.Address, b.City, b.State, b.Zip, a.Phone 
FROM a.ContactTable 
RIGHT JOIN (SELECT DISTINCT Address, City, State, Zip 
      FROM ContactTable) b 
ON a.ID = b.ID 

Этот подзапрос, как создание временной таблицы отбирая только отчетливый адрес, а затем присоединение его к остальной части информации.

Чтобы добавить поиск по вашей новой таблицы добавить следующее

SELECT a.ID, a.CompanyName, b.Address, b.City, b.State, b.Zip, a.Phone 
FROM a.ContactTable 
RIGHT JOIN (SELECT DISTINCT Address, City, State, Zip 
      FROM ContactTable) b 
ON a.ID = b.ID 
RIGHT JOIN SentMailer c 
ON a.ID = c.ID 

WHERE DATEDIFF(mm, c.DateSent, GETDATE()) > 12 --gives you everything that hasn't been sent a mailer within the last year 

Редактировать

Без данных стандартизируется это трудно получить качественные результаты. Я нашел в прошлом больше creative Я должен получить с моими запросами флаг для плохой структуры таблицы или сбора данных. Я думаю, вы все равно должны создать таблицу поиска для ID/DateSent для управления временными рамками для отправки.

Редактировать

Да, я в основном ищу уникальный адрес, город, штат, почтовый индекс. Я бы потребовал только один экземпляр для каждого адреса, чтобы мы могли отправить почтовое сообщение на этот адрес. На данный момент название компании не требуется.

Если это так, вы можете просто сделать следующее:

SELECT DISTINCT Address, City, State, Zip, Phone 
FROM ContactTable 

Имейте в виду, что это не будет записи скраб как Main Street против Main St.

+0

Я попытался выполнить SELECT a.ID, a.CompanyName, b.Address, b.City, b.State, b.Zip, a.Phone FROM a.ContactTable RIGHT JOIN (SELECT DISTINCT Address, City, State, Zip FROM ContactTable) b ON a.ID = b.ID Но была дана ошибка ID не существует. Предположительно, поскольку идентификатор не существует в подзапросе. – RogueSpear00

+0

Ты прав ... Я пропустил это. @Joe Stefanelli правильна, однако ... качество вашей продукции только так хорошо, как качество вашего ввода. Если данные недействительны, вы получите дубликаты независимо. Я уточню свой ответ. – jon3laze

+0

Если я помещаю ID в подзапрос - это отрицает утверждение Distinct? Разве не было бы четким утверждением теперь спорным вопросом, так как все они имеют уникальные идентификаторы? – RogueSpear00

1

RogueSpear, я работаю в адресной проверки (и, таким образом, de-duplication) для SmartyStreets, где мы имеем дело с этим сценарием и решаем проблему.

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

Вы можете пометить дубликаты в таблице, используя что-то вроде CASS-Certified Scrubbing, или вы можете предотвратить дубликаты в точке входа с API, например, LiveAddress. В любом случае, я был бы рад лично помочь вам с любыми другими вопросами.