2009-10-22 3 views
6

У меня есть таблица Access 2003 с ~ 4000 записей, которая была сделана из 17 разных таблиц. Примерно половина этих записей - это дубликаты. Нет уникального идентификационного столбца (id, name и т. Д.). Существует столбец идентификатора, который был автоматически заполнен, когда таблицы были объединены, что означает, что дубликаты не полностью идентичны (хотя этот столбец можно удалить, если это облегчит задачу).Удаление дубликатов в Access 2003

Я использовал мастер запросов Access Duplicates Query Wizard, который дает мне список дублированных записей, но не позволяет мне их удалять (серьезно, какой смысл использовать этот запрос, если я не могу их удалить?). Я попытался преобразовать сгенерированный запрос в запрос удаления, но это изменит количество найденных строк. Я бы изменил sql вручную, но он немного выше меня и имеет длину 7 строк.

Кто-нибудь знает хороший способ избавиться от дубликатов?

ответ

7

Причина, по которой запрос на поиск дубликатов не позволит вам удалить записи, состоит в том, что это в основном просто агрегированный запрос, он подсчитывает количество найденных дубликатов и возвращает случаи, когда счетчик больше 1.

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

Вы должны попытаться удалить все дубликаты записи, кроме одного, за исключением столбца ID при сравнении. Я предлагаю простейший способ сделать это, чтобы сделать запрос make-таблицы всего unique values (выберите Distinct Field1, Field2 ... из MyTable) вместо этого для каждого поля , за исключением для поля ID, используя результаты в a создайте новую таблицу около 2000 записей (если половина дубликатов).

Затем создайте столбец ID на новой таблице, используйте запрос на обновление, чтобы обновить этот идентификатор первого согласующего ID в исходной таблице (вы можете сделать это с помощью DLookup, которая возвращает первое значение выражения, где КРИТЕРИИ верно в DOMAIN).

Функция DLookup() возвращает один значение из одного поля, даже если более , чем одна запись удовлетворяет критериям . Если никакая запись не удовлетворяет критериям , или если в домене нет записей , DLookup() возвращает Null.

Поскольку вы идентифицируете первый идентификатор соответствия на основе всех других полей, которые являются уникальными значениями, непревзойденные идентификаторы будут принадлежать дубликатам. Вы измените отношение PK, идентифицируя первый ключ соответствия, заданный набором уникальных полей. После этого вы должны установить идентификатор PK. Конечно, это предполагает, что идентификатор не имеет неотъемлемого значения, и вам не нужно сохранять один конкретный идентификатор для данной дублированной строки по любому из идентификаторов, принадлежащих другим дублированным строкам. Это предполагает, что вы заботитесь о данных в столбце «Идентификатор», чтобы сохранить его для всех оставшихся строк, иначе просто проигнорируйте шаг DLookup и выберите «Выбрать отдельный» на всех столбцах, кроме идентификатора.

+0

Ага! Эти первые два параграфа имеют большой смысл! Я сделал запрос следующим образом: SELECT DISTINCT blah1, blah2, blah3 и т.д. INTO Новая_таблица ОТ allrecords ... который дал мне 2144 записей, которые, кажется о праве. Это не просто создало копию таблицы без дубликатов? То есть действительно ли мне нужен бит DLookup? –

+2

Да, он скопировал все строки. Вам не нужно делать бит DLookup, если вам не нужно сохранять идентификаторы для всех строк. –

+0

Когда @Dale Halliwell говорит: «Причина, по которой запрос на поиск дубликатов не позволит вам удалить записи, состоит в том, что в основном это всего лишь совокупный запрос», он делает ложную инструкцию. Мастер поиска дубликатов использует агрегированный запрос в подзапросе IN в предложении WHERE, но базовый запрос должен быть доступен для редактирования, если только исходный текст, который вы выбрали для удаления, был доступен для редактирования. –

1

Используйте отборное со всеми столбцами, кроме столбца ID:

SELECT DISTINCTROW Column1, Column2, Column3 
INTO MYNEWTABLE 
FROM TABLE 

Вы можете просто поменять местами имена.

Это решение предоставит вам новую таблицу без дубликатов.

+0

Возможно, я делаю что-то неправильно, но это просто дублирует всю таблицу. –

1

Ниже будет сохранить исходные идентификаторы и сделать это в один шаг:

DELETE FROM table_with_duplicates 
WHERE table_with_duplicates.id NOT IN 
    (SELECT max(id) 
    FROM table_with_duplicates 
    GROUP BY duplicated_field_1, duplicated_field_2, ... 
    ) 

Теперь у вас есть оригинальный таблица без дублей и консервированных идентификаторами. И всегда помните, чтобы делать резервные копии данных перед попыткой больших DELETE.

+0

Я не думаю, что это сработает. Каждая запись имеет отдельный идентификатор, т. Е. Дубликаты одинаково во всех отношениях ИСКЛЮЧАЮТ для столбца id. Если бы был уникальный столбец идентификации, я бы уже закончил! –

+0

в вашем вопросе вы указываете, что идентификатор автозаполнен, который я принимаю, чтобы иметь значение auto-incremented, поэтому этот запрос возвращает повторяющиеся сгруппированные записи и идентификаторы count. это действительно сработает. попробуй! – avguchenko

1
DELETE * FROM table_with_duplicates 
WHERE table_with_duplicates.ID In 
    (SELECT max(ID) 
    FROM table_with_duplicates 
    GROUP BY [duplicated_field_1] 
    HAVING Count(*)>1 
    ) 
0

На самом деле я нашел очень простое решение, потребовалось некоторое время, но все ваши поля его через такие же, как полный отчет дубликата, то просто сделать один запрос с каждого поля и сортировать по «GROUP BY». Таким образом, дубликаты будут объединены, и вы можете просто добавить эту информацию в новую таблицу и переименовать ее так же, как и существующую таблицу. Если у вас есть первичное ключевое поле, вы можете просто игнорировать его в запросе, а затем он все равно будет объединять данные (при условии, что вам не нужны данные в основном поле). Я не знаю, почему никто не упомянул об этом решении, мне потребовалось 5 часов. Придумать. :)

Смежные вопросы