2016-02-20 4 views
1

У меня есть 2 таблицы с разными именами полей, но те же данные. Я хочу импортировать в одну таблицу данные из другой таблицы без создания повторяющихся строк.SQL NOT EXISTS - вставка без дубликатов

Это то, что я попытался (я работаю в Access VBA):

Private Sub Command4_Click() 

Dim SQL As String 

SQL = "INSERT INTO COMPANY(CompanyNumber, CompanyName)" & _ 
      " SELECT Number, Company" & _ 
      " FROM NEW" & _ 
      " WHERE NOT EXISTS " & _ 
      "(SELECT CompanyNumber, CompanyName FROM COMPANY)" 

    DoCmd.RunSQL SQL 

End Sub 

Это возвращает меня, чтобы добавить 0 строк. Что я делаю не так ?

+0

'NOT EXISTS' должен содержать инструкцию' SELECT'. –

+0

Исправления языков, переформатированный код – maxhb

+0

У вас есть первичный ключ в tableA? –

ответ

0

Yesssss, я наконец-то удалось его работать, это был целый день кошмар. Вот оно:

Private Sub Command4_Click() 

Dim SQL As String 

SQL = "INSERT INTO COMPANY(CompanyNumber, CompanyName)" & _ 
      " SELECT DISTINCT Number, Company" & _ 
      " FROM NEW" & _ 
      " WHERE NOT EXISTS " & _ 
      "(SELECT * FROM COMPANY WHERE" & _ 
      " (NEW.Number=COMPANY.CompanyNumber AND NEW.Company=COMPANY.CompanyName)" 

    DoCmd.RunSQL SQL 

End Sub 

@DylanSue спасибо, всем остальным, вы мне очень помогли. Похоже, MS-доступ довольно странный при выполнении дубликатов. Я добавил DISTINCT, потому что вторая таблица имеет много одинаковых записей. Однако, если я дважды исполняю один и тот же код, он снова импортирует 2 строки - один из них пуст в обоих столбцах и один только в одном столбце. Как я могу избежать пустых записей для обоих столбцов? (Если один столбец пуст, тогда он также должен импортировать).

+0

Проверьте мои обновленные ан. –

+0

У меня есть, но он все еще не работает. Я должен был использовать IS NULL вместо '', но когда я это делаю и запускаю код дважды, SQL все еще импортирует одну строку, где 1 столбец пустой, а другой нет. Но если я использую другой И НЕ для обоих случаев, когда 1 столбец пуст, тогда импорт этой строки не происходит в первом случае тоже ... – LuckyLuke82

+0

Я не получил его. –

0

Создайте уникальный индекс в таблице (table_1), где вы хотите вставить все столбцы, которые должны быть уникальными. Затем выполните это. Имя столбцов не важно, но порядок полей должен быть одинаковым. Если вы не должны указать порядок столбцов в таблице 2. Изменение * до FIELDNAME1, fieldname3, FIELDNAME2 ...

INSERT IGNORE INTO table_1 
    SELECT * FROM table_2; 
+0

Ňot работает. У меня есть уникальный ключ для записей на первой таблице, а не во второй - это просто электронная таблица Excel. Я также пробовал это: INSERT IGNORE INTO TableA (AField1, AField2) "& _ " SELECT * FROM TableB (BField1, BField2); " – LuckyLuke82

+0

Позвольте мне еще раз сказать: TableA имеет 3 столбца - ID_Number, номер компании и название компании - в том же порядке. TableB имеет только два столбца: номер компании и название компании, в том же порядке - нет идентификатора в этом списке, это просто таблица Excel. – LuckyLuke82

0

Поскольку с MS-ACCESS, решение становится все более сложным.

Кроме того, чтобы правильно обрабатывать NULL, добавляется больше фильтров. Для NULL, NULL строки, он не будет вставлен в TableA, тогда как xx, NULL будет вставлен.

Для краткости требуется INSERT INTO ... SELECT заявление, как:

INSERT INTO TableA(Company_Number, Company_Name) 
SELECT 
    DISTINCT Company_Number, Company_Name 
FROM 
    TableB 
WHERE NOT EXISTS 
      (SELECT 
       1 
      FROM 
       TableA 
      WHERE 
       (TableA.Company_Number=TableB.Company_Number OR (TableA.Company_Number IS NULL AND TableB.Company_Number IS NULL)) AND 
       (TableA.Company_Name=TableB.Company_Name OR (TableA.Company_Name IS NULL AND TableB.Company_Name IS NULL)) AND 
       NOT (TableB.Company_Number IS NULL AND TableB.Company_Name IS NULL)); 

Полный демо прилагается (у меня нет условий для MS-ACCESS, и это выполняется в MySQL 5.7). ,

SQL:

create table TableA(ID_Number int auto_increment primary key, Company_Number int, Company_Name varchar(200)); 
create table TableB(Company_Number int, Company_Name varchar(200)); 

insert into TableA(Company_Number, Company_Name) values 
(1,'A'), 
(2,'B'); 
insert into TableB(Company_Number, Company_Name) values 
(2,'B'), 
(3,'C'), 
(4,NULL), 
(NULL,'D'); 
SELECT * FROM TableA; 
SELECT * FROM TableB; 
INSERT INTO TableA(Company_Number, Company_Name) 
SELECT 
    DISTINCT Company_Number, Company_Name 
FROM 
    TableB 
WHERE NOT EXISTS 
      (SELECT 
       1 
      FROM 
       TableA 
      WHERE 
       (TableA.Company_Number=TableB.Company_Number OR (TableA.Company_Number IS NULL AND TableB.Company_Number IS NULL)) AND 
       (TableA.Company_Name=TableB.Company_Name OR (TableA.Company_Name IS NULL AND TableB.Company_Name IS NULL)) AND 
       NOT (TableB.Company_Number IS NULL AND TableB.Company_Name IS NULL)); 
SELECT * FROM TableA; 

INSERT INTO TableA(Company_Number, Company_Name) 
SELECT 
    DISTINCT Company_Number, Company_Name 
FROM 
    TableB 
WHERE NOT EXISTS 
      (SELECT 
       1 
      FROM 
       TableA 
      WHERE 
       (TableA.Company_Number=TableB.Company_Number OR (TableA.Company_Number IS NULL AND TableB.Company_Number IS NULL)) AND 
       (TableA.Company_Name=TableB.Company_Name OR (TableA.Company_Name IS NULL AND TableB.Company_Name IS NULL)) AND 
       NOT (TableB.Company_Number IS NULL AND TableB.Company_Name IS NULL)); 
SELECT * FROM TableA; 

Выход:

mysql> SELECT * FROM TableA; 
+-----------+----------------+--------------+ 
| ID_Number | Company_Number | Company_Name | 
+-----------+----------------+--------------+ 
|   1 |    1 | A   | 
|   2 |    2 | B   | 
+-----------+----------------+--------------+ 
2 rows in set (0.00 sec) 

mysql> SELECT * FROM TableB; 
+----------------+--------------+ 
| Company_Number | Company_Name | 
+----------------+--------------+ 
|    2 | B   | 
|    3 | C   | 
|    4 | NULL   | 
|   NULL | D   | 
+----------------+--------------+ 
4 rows in set (0.00 sec) 

mysql> INSERT INTO TableA(Company_Number, Company_Name) 
    -> SELECT 
    ->  DISTINCT Company_Number, Company_Name 
    -> FROM 
    ->  TableB 
    -> WHERE NOT EXISTS 
    ->    (SELECT 
    ->     1 
    ->    FROM 
    ->     TableA 
    ->    WHERE 
    ->     (TableA.Company_Number=TableB.Company_Number OR (TableA.Company_Number IS NULL AND TableB.Company_Number IS NULL)) AND 
    ->     (TableA.Company_Name=TableB.Company_Name OR (TableA.Company_Name IS NULL AND TableB.Company_Name IS NULL)) AND 
    ->     NOT (TableB.Company_Number IS NULL AND TableB.Company_Name IS NULL)); 
Query OK, 3 rows affected (0.00 sec) 
Records: 3 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM TableA; 
+-----------+----------------+--------------+ 
| ID_Number | Company_Number | Company_Name | 
+-----------+----------------+--------------+ 
|   1 |    1 | A   | 
|   2 |    2 | B   | 
|   3 |    3 | C   | 
|   4 |    4 | NULL   | 
|   5 |   NULL | D   | 
+-----------+----------------+--------------+ 
5 rows in set (0.00 sec) 

mysql> 
mysql> INSERT INTO TableA(Company_Number, Company_Name) 
    -> SELECT 
    ->  DISTINCT Company_Number, Company_Name 
    -> FROM 
    ->  TableB 
    -> WHERE NOT EXISTS 
    ->    (SELECT 
    ->     1 
    ->    FROM 
    ->     TableA 
    ->    WHERE 
    ->     (TableA.Company_Number=TableB.Company_Number OR (TableA.Company_Number IS NULL AND TableB.Company_Number IS NULL)) AND 
    ->     (TableA.Company_Name=TableB.Company_Name OR (TableA.Company_Name IS NULL AND TableB.Company_Name IS NULL)) AND 
    ->     NOT (TableB.Company_Number IS NULL AND TableB.Company_Name IS NULL)); 
Query OK, 0 rows affected (0.00 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM TableA; 
+-----------+----------------+--------------+ 
| ID_Number | Company_Number | Company_Name | 
+-----------+----------------+--------------+ 
|   1 |    1 | A   | 
|   2 |    2 | B   | 
|   3 |    3 | C   | 
|   4 |    4 | NULL   | 
|   5 |   NULL | D   | 
+-----------+----------------+--------------+ 
5 rows in set (0.00 sec) 
+1

Это будет то же самое, что и 'INSERT IGNORE', и должен быть определен уникальный ключ –

+0

Я тоже пробовал это, не работая, синтаксическая ошибка в предложении WHERE. – LuckyLuke82

+0

В этом утверждении нет предложения WHERE. –

0

Если вы по какой-то причине не хотите, чтобы создать уникальный ключ на (AField1, AField2) вам просто нужно добавить в ваш SELECT 1 FROM TablA WHERENOT EXISTS часть:

INSERT INTO TableA (AField1, AField2) 
    SELECT BField1,Bfield2 
    FROM TableB 
    WHERE NOT EXISTS (
     SELECT 1 FROM TableA 
     WHERE TableB.BField1 = TableA.AField1 AND TableB.BField2 = TableA.AField2 
    ) 

Вы также можете попробовать исключить LEFT JOIN:

INSERT INTO TableA (AField1, AField2) 
    SELECT BField1,Bfield2 
    FROM TableB 
    LEFT JOIN TableA ON TableB.BField1 = TableA.AField1 AND TableB.BField2 = TableA.AField2 
    WHERE TableA.AField1 IS NULL 
+0

Чтобы ответить Павлу Шпигелю - я тоже пробовал это раньше, но не работал: «INSERT INTO TableA (AField1, AField2)» & _ «SELECT BField1, Bfield2» & _ «FROM TableB» & _ «ГДЕ НЕ СУЩЕСТВУЕТ (SELECT * FROM TableA WHERE (TableB.BField1 = TableA.AField1 AND TableB.BField2 = TableA.AField2)) " – LuckyLuke82

+0

Он работает для меня и работает для [sqlfiddle] (http://www.sqlfiddle.com/#!9/14cb9/2). Что значит «не работает»? Вставляются ли повторяющиеся строки? –

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