Страницы: 1
RSS
Как в SQL-запросе игнорить дубли?
 
Подскажите, пожалуйста, есть ли возможность при вставке пула строк из Excel в таблицу Access отвергать дубликаты записей, но при этом записывать уникальные? Я при создании таблицы делаю уникальными несколько полей, но при дублировании система просто возвращает исключение и не копирует ничего. Прочитал, что в MySql есть такой параметр как Ignore Duplicate Key (Ignore_Dup_Key), но в VBA он у меня на сработал.
 
Use select distinct
Изменено: doober - 10.10.2019 22:47:44
 
doober, у меня обратное действия, я же вставляю, а не извлекаю )
 
Доброе время суток
Цитата
Ungrateful написал:
, я же вставляю
Сергей написал о такой конструкции вставки INSERT INTO конечный_объект [(поле1[, поле2[, …]])] [IN внешняя_база_данных] SELECT [источник.]поле1[, поле2[, …] FROM выражение_таблицы. Вот в том Select и нужно использовать Distinct
 
Андрей VG, доброе утро! Я, наверное, не совсем точно написал, я пытаюсь сделать, чтобы игнорировались дубли вносимых значений по отношению к уже имеющимся в базе данным. Попробую предложенный вариант, но по моим ощущениям, он уберет дубли из той таблицы, которую я вставляю (т.е. дубли из источника), но наличие строк в базе, дублирщих те, которые я вставляю, все равно приведут к возникновению исключения.
Изменено: Ungrateful - 11.10.2019 08:00:21
 
Цитата
Ungrateful написал:
Я наверное не совсем точно написал,
это точно. тоже понял как Андрей VG,
Ну так тогда запрос и должен брать две таблицы 1 и 2 и разницу вставлять в одну из них.
По вопросам из тем форума, личку не читаю.
 
Доброе время суток
Цитата
БМВ написал:
и должен брать две таблицы 1 и 2 и разницу вставлять в одну из них
Привет, Михаил
Ungrateful, вы не стесняйтесь продемонстрировать структуру данных и описание первичного ключа. Решается, в общем-то банальным подзапросом, мышкоклацательного решения только тут нет.
 
Андрей VG, таблица примерно такая:
Код
strSQL = "CREATE TABLE [" & dbTableName & "] " & _
   "([NUM] counter, [Период] date NOT NULL, [Дебет счет] string, [Дебет] double, " & _
   "[Кредит счет] string, [Кредит] double," & _
   "UNIQUE ([Период],[Дебет счет],[Дебет],[Кредит счет],[Кредит]))"

и вставлять тогда как-то так, проще варианта нет?
Код
strSQL = "INSERT INTO [" & dbTableName & "] SELECT * FROM [" & xlSheetName & "$] b " & _
   "IN '" & xlFile & "' [Excel 12.0; Xml; hdr=yes;]" & _
   "WHERE [Период] <> b.[Период] AND [Аналитика Дт] <> b.[Аналитика Дт] AND ..."
но тут что-то не так, не отбирает...
Изменено: Ungrateful - 11.10.2019 11:39:45
 
как вариант в Access сделать ключ по полям в таблице, куда вставляют данные, которые будут уникальные, и тогда он не даст вставлять повторы.
Изменено: aibolit - 11.10.2019 10:08:21
 
aibolit, так он конкретно не дает, вставку всей таблицы отвергает, а не только дубликатов. Я вставляю не по строкам, а сразу большим пулом.
 
Так ничего и не вышло. Крутил запрос и так и эдак, но выводит либо все подряд, либо пустые строки.
Код
strSQL = "INSERT INTO [" & dbTableName & "] SELECT * FROM [" & xlSheetName & "$] b " & _
   "IN '" & xlFile & "' [Excel 12.0; Xml; hdr=yes;]" & _
   "WHERE [" & dbTableName & "].[Период] <> b.[Период] AND [" & dbTableName & "].[Аналитика Дт] <> b.[Аналитика Дт]"
вот этот код выдает ошибку "отсутствует значение одного или нескольких параметров".
 
Цитата
Ungrateful написал:
Так ничего и не вышло
Правильно ли я понимаю, что чёткого описания структур таблиц не будет, не говоря уж о примере? Лучше ждать, чем правила форума соблюдать?
 
Андрей VG, значит я не так вас понял про структуру. Думал нужен запрос сосструктурой, который я написал. Сейчас сделаю файлы
 
Андрей VG,  сделал файлик, только не добавляется Access, много весит даже пустой. Если не сложно, создайте файл Db.accdb
В нем два листа и две кнопки:
- один лист "База" с данными, которые нужно первоначально добавить в базу
- второй лист "Новые записи" с данными, часть из которых совпадает с данными на первом листе (выделил желтым цветом).
Оставил строку с одним из вариантов, как пытался добавить записи, отсутствующие в таблице.
Изучил книгу по SQL (Мартин Грабер), но там есть далеко не все, нет специфики VBA. Можете подсказать еще какую-то литературу?
Заранее спасибо!
 
Код
Sub FromExcelToDB(xlFile As String, xlSheetName As String, dbFile As String, dbTableName As String, addStr As String, bLoad As Boolean)
    Dim dbcn As ADODB.Connection
    Dim ColumnsNames As String, strSql As String
    
    ColumnsNames = "[NUM] counter," & _
                   "[Период] date NOT NULL," & _
                   "[Имя] string," & _
                   "[Сумма] double," & _
                   "UNIQUE ([Период],[Имя],[Сумма])"
    
    Set dbcn = New ADODB.Connection
    dbcn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & dbFile
    
    If bLoad Then 'Если Загрузка таблицы, то стираем старую и создаем новую
        On Error Resume Next
        strSql = "DROP TABLE [" & dbTableName & "]"
        dbcn.Execute strSql
        On Error GoTo 0
        
        strSql = "CREATE TABLE [" & dbTableName & "] (" & ColumnsNames & ")"
        dbcn.Execute strSql
    End If
        
    'Вставляем данные в таблицу
    strSql = "INSERT INTO  [" & dbTableName & "]SELECT t2.* FROM [" & dbTableName & "] AS t1 RIGHT JOIN (SELECT t.* FROM [" & xlSheetName & "$] t IN '" & xlFile & "' [Excel 12.0; Xml; hdr=yes;]) AS t2 ON t2.[Период]=t1.[Период] WHERE t1.[Период] is null"
'    strSql = strSql & addStr
             
    dbcn.Execute strSql
    
    dbcn.Close
    Set dbcn = Nothing
 End Sub
Изменено: Андрей Лящук - 11.10.2019 18:25:29 (че-то меня прет...)
 
Андрей Лящук, круто, спасибо! Буду теперь ваш запрос раскодировать, джоинами еще не пользовался )
 
В отдельно взятой таблице запрос работал замечательно, но когда попытался применить в деле, возникла ошибка. Прочитал про JOIN, поэкспериментировал, но все равно не могу понять, почему перестало работать. Есть подозрение, что из-за добавления пустых столбцов, которые я заполняю уже другим запросом прямо в Access.
Изменил пример, под этот случай.
 
Подумал, что может не самая хорошая идея писать в ON так много связей, попробовал так, но тоже безрезультатно:
Код
ON (t2.[Период] & t2.[Сумма] & t2.[Имя]) = (t1.[Период] & t1.[Сумма] & t1.[Имя])
Вроде бы должны сравниваться получившиеся после объединения строки? Потому что в первом случае, как я понял, каждому периоду, каждой сумме и каждому имени ищутся свои соответствия, поэтому если они (в любой комбинации) встречаются в изначальной таблице, то и будут выведены в промежуточную таблицу как пустые строки. И, соответственно, отобраны условием WHERE.

Все, в итоге этим методом получилось, но пришлось добавить много полей. И очень долго обрабатывается запрос - это основной минус. Лучше уж пусть отвергает попытку добавить такую таблицу.
Изменено: Ungrateful - 16.10.2019 15:11:57 (Вопрос решился)
Страницы: 1
Наверх