Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как удалить дубликаты?
 
 автор: Аленка   (19.10.2008 в 16:26)   личное сообщение
 
 

В одной из таблиц некоторые записи могут дублироваться полностью, даже код (так как эта таблица создается запросом и в ней нет ключевых полей).
Как сделать так, чтобы удалить дубликаты?
Смысл я понимаю. Создать запрос на выборку дубликатов и этот запрос сделать запросом на удаление записей, являющихся дублирующими.
Вопрос вот какой: как сделать запрос, где будут видны ТОЛЬКО дубликаты?

Если я делаю с помощью мастера запрос на поиск дубликатов, то в данном запросе видны не только дубликаты, но и дублируемые записи. То есть если запись дублируется 2 раза, то в данном запросе видны все 3 записи. Соответственно, если я из этого запроса удалю записи, то удалятся и дубликаты и дублируемые.

А как исключить из запроса дублируемые записи и показать ТОЛЬКО ДУБЛИКАТЫ?

  Ответить  
 
 автор: час   (19.10.2008 в 17:05)   личное сообщение
 
 

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

  Ответить  
 
 автор: час   (19.10.2008 в 17:08)   личное сообщение
 
 

создай табличку не запросом,
задай свойства для поля которые не допускают повторения
и запросом делай добавление записей
те что не влезут - дубляжи - будут лешать в таблице - ошибки вставки

  Ответить  
 
 автор: Аленка   (19.10.2008 в 23:33)   личное сообщение
 
 

Чтобы не заморачиваться, все упростим.
Есть таблица с записями:
Поле1......поле2........поле3
1..................33..............44
тт..................мм..............нн
1.................33...............44
тт................мм................нн

Как видно, здесь лишь две уникальные записи. Остальные две - это их дубликаты. ВСЕГО 4 записи.
И их, соответственно, нужно удалить. Как?
Если создать запрос на поиск повторяющихся записей с помощью мастера запросов, то в запросе он покажет как раз все эти 4 записи. А реально нужно показать только две записи, то есть дубликаты, чтобы можно было их удалить запросом на удаление.

  Ответить  
 
 автор: SRG   (20.10.2008 в 00:28)   личное сообщение
 
 

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

  Ответить  
 
 автор: Lvm   (20.10.2008 в 06:42)   личное сообщение
 
 

Отличить записи, у которых значения всех полей совпадают по определению невозможно. Да они и не отличаются ничем с точки зрения СУБД. Следовательно невозможно и определить которые из них оригиналы, а которые дубликаты.
Почистить таблицу от дубликатов можно так:
1. Создайте в таблице поле идентификатора (тип Счетчик, Совпадения не допускаются).
2. Выполните запрос вида:
DELETE a.*
FROM Таблица1 AS a
WHERE EXISTS (SELECT b.* FROM Таблица1 as b WHERE (a.ID>b.ID) AND (a.Поле1=b.Поле1) AND (a.Поле2=b.Поле2));
В таблице останутся дубликаты с наименьшим значением идентификатора (можно сделать наоборот, роли не играет).
В принципе можно так и работать дальше - счетчик получает уникальные значения автоматически и ни на какие другие операции не влияет.

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

  Ответить  
 
 автор: Аленка   (20.10.2008 в 14:30)   личное сообщение
 
 

Спасибо за советы. Но я объясню, откуда у меня дубликаты. В само БД у меня их нет и быть не может. А здесь просто данные вставляются из файла Иксель. Как повесить проверку того, что такие данные уже вставлялись, я не знаю. А пользователь может нажать кнопку случайно 2, 3 раза и т.п. и суммы сразу поедут. Поэтому я решила сделать через удаление дубликатов.
В случае вставки данных несколько раз записи получаются полностью идентичные, при этом вставляется и Код Записи в поле, где допускаются повторения, соответственно, я уже по одному Коду Записи могу однозначно определить повторяющиеся записи.
Вот.

  Ответить  
 
 автор: shaucha   (20.10.2008 в 14:41)   личное сообщение
 
 

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

  Ответить  
 
 автор: Аленка   (20.10.2008 в 14:46)   личное сообщение
 
 

попробовала я и
DELETE a.*
FROM Таблица1 AS a
WHERE EXISTS (SELECT b.* FROM Таблица1 as b WHERE (a.ID>b.ID) AND (a.Поле1=b.Поле1) AND (a.Поле2=b.Поле2));
и
distinct

Первое удаляет все записи из таблицы, которые имеют дубликаты. При этом удаляются все экземпляры.

А distinct делает запрос нередактируемым и соответственно записи вообще не удаляются.

  Ответить  
 
 автор: Lvm   (21.10.2008 в 06:42)   личное сообщение
 
 

>Первое удаляет все записи из таблицы, которые имеют
>дубликаты. При этом удаляются все экземпляры.

Не могёт такого быть!!! Специально проверил. Для Вашего случая будет:
DELETE a.*
FROM Таблица1 AS a
WHERE EXISTS (SELECT b.* FROM Таблица1 as b WHERE (a.ID>b.ID) AND (a.КодЗаписи=b.КодЗаписи));

Как повесить проверку? В свойствах поля указать Индексированное поле:Да (Совпадения не допускаются).
Если нужно обеспечить уникальность не отдельного поля, а сочетания значений нескольких полей, в конструкторе выделяете эти поля и устанавливаете у них свойство "Ключевое поле" (одновременно у всех). Остается обработать реакцию системы на ошибку вставки.

  Ответить  
 
 автор: час   (21.10.2008 в 08:41)   личное сообщение
 
 

чтоб не было дубликатов делаю - так
на нажатие кнопки

If PEREBROS_peremehenie(Dialog_FIle_OPEN("Укажите файл загрузки", "Загрузить")) = False Then Exit Sub


сама функция:


Public Function PEREBROS_peremehenie(Path_Peremeheuie As String) As Boolean
' переброс товара из перемещения на склад
PEREBROS_peremehenie = True
      Dim rstOtkuda As DAO.Recordset 'Объявляем рекордсет
      Dim rstkuda As DAO.Recordset 'Объявляем рекордсет
      Dim BAZA As DAO.Database 'Объявляем базу
On Error GoTo PEREBROS_peremehenie_Error
'-------------------------------------------------------------------------------
      Set BAZAName = CurrentDb
      Set BAZA = OpenDatabase(Path_Peremeheuie)
     If Nalichie_Tablici_v_Drugoy_Baze("PEREMEHENIE_TBL", Path_Peremeheuie) = False Then
     Call MsgBox("В указанном файле нет данных для загрузки!!!", vbCritical, "Предупреждение")
     PEREBROS_peremehenie = False
     Exit Function
     End If
      Set rstOtkuda = BAZA.OpenRecordset("PEREMEHENIE_TBL")
      Set rstkuda = BAZAName.OpenRecordset("Vrem_prihod_TBL")
      
Do Until rstOtkuda.EOF
    rstkuda.AddNew
    rstkuda!Номер_документа = rstOtkuda!Номер_документа
    rstkuda!Дата_документа = rstOtkuda!Дата_документа
    rstkuda!Склад_Отправитель = rstOtkuda!Склад_Отправитель
    rstkuda!Склад_Получатель = rstOtkuda!Склад_Получатель
    rstkuda!Наименование = rstOtkuda!Наименование
    rstkuda!цена = rstOtkuda!цена
    rstkuda!Количество = rstOtkuda!Количество
    rstkuda!Сумма = rstOtkuda!Сумма
    rstkuda!Код_Товара = rstOtkuda!Код_Товара
    rstkuda!Единица = rstOtkuda!Единица
    rstkuda!Штрихкод = rstOtkuda!Штрихкод
    rstkuda!Группа = rstOtkuda!Группа
    rstkuda!Артикул = rstOtkuda!Артикул
    rstkuda!Уже_Имеем = Proverka_Nalichiya(rstOtkuda!Номер_документа, rstOtkuda!Дата_документа, rstOtkuda!Код_Товара)' вот тут проверяем имеется ли такой товар на складе
rstkuda.Update
rstOtkuda.MoveNext
Loop

  rstOtkuda.Close
  rstkuda.Close
  Set rstOtkuda = Nothing
  Set rstkuda = Nothing
  BAZAName.Close
  Set BAZAName = Nothing
'===========Проверка загруженного  ============
  If DCount("*", "Vrem_Prihod_TBL") = 0 Then
MsgBox "Не уалось ЗАГРУЗИТЬ ПРИХОД"
PEREBROS_peremehenie = False
End If
'-------------------------------------------------------------------------------
On Error GoTo 0
Exit Function
PEREBROS_peremehenie_Error:
If Err.Number = 3078 Then MsgBox "Некорректные данные в файле перемещения " & Path_Peremeheuie
Call Zapis_ERR("OBMEN_MOD" & "процедура->" & "PEREBROS_peremehenie", Err.Number, Err.Description)


  
End Function


может и Вам поможет избежать дублей.......

  Ответить  
 
 автор: час   (21.10.2008 в 08:45)   личное сообщение
 
 

првека наличия

Public Function Proverka_Nalichiya(nomer As String, Data_Dok As Date, Kod_Tovara As String) As Boolean
Proverka_Nalichiya = False
      Dim rstGde As DAO.Recordset 'Объявляем рекордсет
      Dim BAZAName1 As DAO.Database 'Объявляем базу
Set BAZAName1 = CurrentDb
Set rstGde = BAZAName1.OpenRecordset("DOK_Prihod_TBL")
With rstGde
If .EOF = True Then GoTo Exit_Function
        .MoveFirst
        .MoveLast
    If .RecordCount = 0 Then GoTo Exit_Function
    .MoveFirst
   Do Until .EOF
  If !Номер_документа = nomer Then
            If !Дата_документа = Data_Dok Then
                     If !Код_Товара = Kod_Tovara Then
                     Proverka_Nalichiya = True
                     GoTo Exit_Function:
                     End If
            End If
    End If
    .MoveNext
    Loop

End With


Exit_Function:
  rstGde.Close
  Set rstGde = Nothing
  BAZAName1.Close
  Set BAZAName1 = Nothing

End Function

  Ответить  
 
 автор: час   (21.10.2008 в 08:48)   личное сообщение
 
 

поле уже имеем - оно (boolean)
его используем что бы показать юзеру, что он не прав с этими записями.
и выводим список который не стоит дублировать - успокойся хватит жать на кнопку - это уже зенесено!!!!!!!!!!!
0-не имеем
-1-имеем
но можно и иначе посмотрите может найдёте решение - для себя........

  Ответить  
 
 автор: Аленка   (21.10.2008 в 11:23)   личное сообщение
 
 

час - Вам огромное спасибо. Это то, что нужно. Гораздо лучше, чем иметь дело с дубикатами!!!!!!!!!!!!!!!!

  Ответить  
 
 автор: час   (21.10.2008 в 20:31)   личное сообщение
 
 

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList