2016-03-13 27 views
0

我有3个表 - 表1 &表2其中有记录,表3中它们的差异应该插入。这是我现在有:访问SQL - 插入不匹配的记录

SQL = "INSERT INTO Table3 (Field1,Field2)" & _ 
     "SELECT Table2.Field1, Table2.Field2" & _ 
     " FROM Table2 LEFT JOIN Table1 ON Table2.Field1 = Table1.Field1" & _ 
     " OR Table2.Field2 = Table1.Field2" &_ 
     " WHERE (((Table1.Field1) Is Null) OR ((Table1.Field2) Is Null))" & _ 
     " AND NOT (Table2.Field1 IS NULL AND Table2.Field2 IS NULL)" 

该查询成功地插入了不匹配的记录表3中,但是当我再次运行此查询,应该不会再被插入任何东西,查询仍然插入1条记录在表3中,其中一个表1或表2中的字段为空。

如何消除这种情况发生,缺陷在哪里?

编辑:这里是从表样品....

Table1: 
CompanyNo CompanyName 
111   Microsoft 
      Apple 
333   Oracle 

Table2: 
CompanyNo CompanyName 
111   Microsoft 
222   Apple 
333   Oracle 
      Intel 
555   Google 

Then Table3 should result differences: 
CompanyNo CompanyName 
222   Apple 
      Intel 
555   Google 

而上的代码结果第一次运行是正确的,但是当我再次运行它,“英特尔”的记录再次显示 - 但它不该'因为Table2中的所有新数据都已经在Table1中准备好了(我在这个Query之后对Table1执行INSERT和UPDATE,所以“Table”中的“Intel”记录已经准备好了)。

+0

它可能与'JOIN ON'子句中的'OR'有关。 – Parfait

+0

是的,可能。但是我尝试了各种各样的与AND,OR和ON,LEFT JOIN,INNER JOIN的组合,并且在第二次运行时无法消除该空插入。 – LuckyLuke82

+0

有些事情我不清楚。再次运行追加查询将再次向表中添加相同数量的记录。没有检查记录是否已经在表格中。所以如果它第一次追加10条记录,那么它会在第二,第三......时间再次执行。我错过了什么吗? – ehh

回答

0

你只想领域从Table2,所以我会用not exists

select t2.Field1, t2.Field2 
from table2 as t2 
where not exists (select 1 
        from table1 as t1 
        where (t1.field1 = t2.field1 or t1.field1 is null and t2.field1 is null) or 
         (t1.field2 = t2.field2 or t1.field2 is null and t2.field2 is null) 
       ); 

如果移动NULL比较逻辑的on子句您可能会得到类似的结果。但在MS Access中这可能是不可能的。

+0

我试过了你的建议,但没有奏效。正如你写的那样没有做任何事情,但是当你在第一次选择时加入“INSERT INTO IN TABLE3 ...”),那么它不会插入记录,哪里有一个字段为Null,即使是第一次运行的代码。 – LuckyLuke82

0

考虑将追加查询分解为两个操作,分别捕获表1和表2的差异。现在,你正试图两者的差异和空插入结合是趴在不被参考的选择列从表1的区别:

table1diffSQL = "INSERT INTO Table3 (Field1,Field2)" & _ 
       "SELECT Table1.Field1, Table1.Field2" & _ 
       " FROM Table1 LEFT JOIN Table2 ON Table1.Field1 = Table2.Field1" & _ 
       " AND Table1.Field2 = Table2.Field2" & _ 
       " WHERE ((Table2.Field1) Is Null OR (Table2.Field2) Is Null)" 


table2diffSQL = "INSERT INTO Table3 (Field1,Field2)" & _ 
       "SELECT Table2.Field1, Table2.Field2" & _ 
       " FROM Table2 LEFT JOIN Table1 ON Table1.Field1 = Table2.Field1" & _ 
       " AND Table1.Field2 = Table2.Field2" & _ 
       " WHERE ((Table1.Field1) Is Null OR (Table1.Field2) Is Null)" 

编辑(每个操作的样本数据)

SELECT Table2.CompanyNo, Table2.CompanyName 
FROM Table2 LEFT JOIN Table1 
ON Table1.CompanyNo = Table2.CompanyNo 
AND Table1.CompanyName = Table2.CompanyName 
WHERE Table1.CompanyNo Is Null OR Table1.CompanyName Is Null 

结果

CompanyNo CompanyName 
     222 Apple 
      Intel 
     555 Google 
+0

谢谢Parfait,我试过了,但没有成功,你确定你没有犯错误吗?因为我在你的JOIN中看到了相似的行--Table1.field1 = Table2.Field2 AND Table1.Field2 = Table2.Field2在两个子句中?......但是,你的建议插入所有只有一个字段为空的记录,只有那个,没有别的。 – LuckyLuke82

+0

是的,'JOIN'语句是相同的,但是'FROM'表和'WHERE'子句是不同的。要捕获两个表之间的任何字段的差异,那么这应该工作。你能提供一些类型的样本数据和期望的结果吗? – Parfait

+0

怎么样?我可以在这里粘贴文件吗? – LuckyLuke82

0

我准备为了一个小例子,以确保我们在同一页上。

enter image description here

如果这是你在找什么,所以你可以使用UNION ALL。

INSERT INTO Table3 
SELECT * 
FROM (SELECT Table1.Field1 , Table1.Field2 FROM Table1 LEFT JOIN Table2 ON  
Table1.Field1 = Table2.Field1 WHERE Table2.Field1 is Null 
UNION ALL 
SELECT Table2.Field1 , Table2.Field2 FROM Table2 LEFT JOIN Table1 ON  
Table1.Field1 = Table2.Field1 WHERE Table1.Field1 is Null 
) AS UnMatchedTable; 

正如我之前所说的,再次运行它会再次添加相同的记录。

+0

@eeh,我试过了,但没有做任何事情。第一个 - INSERT没有“(Field1,Field2)”?....第二个 - 在子句中做什么是“AS UnmatchedTable”?如果查询可以工作,那么不应该在第二次运行时添加任何记录 - 因为Table1和Table2没有任何不同的记录。 – LuckyLuke82

+0

INSERT没有“(Field1,Field2)”?这是一个有效的语法。 作为UnmatchedTable,只是从嵌套部分返回的临时表的名称。 一次又一次地运行查询会将记录添加到Table3中,因为它们是独立的。 – ehh