【问题标题】:Access SQL - INSERT unmatched records访问 SQL - 插入不匹配的记录
【发布时间】:2016-03-13 13:57:28
【问题描述】:

我有 3 个表 - 表 1 和表 2 有记录,表 3 应该插入它们的差异。这是我现在拥有的:

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)"

此查询成功在 Table3 中插入​​不匹配的记录,但是当我再次运行此查询并且不应再插入任何内容时,查询仍会在 Table3 中插入​​ 1 条记录,其中 Table1 或 Table2 中的字段之一为 Null。

我怎样才能避免这种情况发生,缺陷在哪里?

编辑:这是表格中的示例....

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

并且在第一次运行代码时结果是正确的,但是当我再次运行它时,再次显示“Intel”记录 - 但它不应该因为 Table2 中的所有新数据都已经在 Table1 中(我正在执行 INSERT 和在此查询之后更新到 Table1,因此“Intel”记录已经在 Table1 中)。

【问题讨论】:

  • 这可能与JOIN ON子句中的OR有关。
  • 是的,可能。但是我已经尝试了 AND、OR 和 ON、LEFT JOIN、INNER JOIN 的各种组合,并且无法在第二次运行时消除空插入。
  • 我不清楚。再次运行追加查询将再次将相同数量的记录添加到表中。没有检查记录是否已经在表中。因此,如果它第一次附加 10 条记录,那么它将在第二次、第三次……时再次执行。我错过了什么吗?
  • 解释起来有点复杂 - 但简而言之 - 在表 1 的查询之后使用了很多查询。但是对于这个查询:在执行查询之前,所有内容都从 Table3 中删除,所以不表中没有记录。此表用于显示在 Table1 中导入新数据时更改的数据,但问题是第二次运行代码,它在 Table3 中插入​​记录,其中空白字段已在 Table1 中,未更改。
  • 哦,还有 Table2?那只是用于导入 Access,这样我就可以在不重复的情况下导入 Table1。这就是为什么要查询 Table2 - 它有所有新数据,而 Table1 有旧数据。而表 3 需要这两者之间的差异。

标签: sql ms-access vba


【解决方案1】:

您只需要来自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 中可能是不可能的。

【讨论】:

  • 我尝试了您的建议,但没有奏效。正如您所写的那样,什么也没做,但是在您的第一个选择上方添加“ INSERT INTO Table3 ....) - 然后它不会在有一个字段 Null 的地方插入记录,即使在第一次运行代码时也是如此。跨度>
【解决方案2】:

考虑将附加查询拆分为两个操作,分别捕获表 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)"

EDIT(根据 OP 的样本数据)

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

【讨论】:

  • 谢谢 Parfait,我试过了,但没用。你确定你没有犯错吗?因为我在您的 JOIN 中看到类似的行 - Table1.field1=Table2.Field2 AND Table1.Field2=Table2.Field2 在两个子句中?...但是,您的建议插入所有有一个字段为空的记录,只有那个,什么都没有否则。
  • 是的,JOIN 语句相同,但FROM 表和WHERE 子句不同。如果您试图捕获两个表之间任一字段的差异,那么这应该可以。您能否提供某种类型的样本数据和期望的结果?
  • 怎么样?我可以在这里粘贴文件吗?
  • 只需将示例数据添加到您的帖子中。表 1 和表 2 的几行以及表 3 的结果。
  • 这里是,检查我编辑的问题,我希望你现在明白了。
【解决方案3】:

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

如果这是您正在寻找的,那么您可以使用 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;

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

【讨论】:

  • @eeh,我试过了,但什么也没做。首先-不带“(Field1,Field2)”的INSERT ?....第二个-“AS UnmatchedTable”在子句中做什么?如果查询有效,则不应在第二次运行时添加任何记录 - 因为 Table1 和 Table2 没有任何不同的记录。
  • 插入不带“(Field1,Field2)”?这是一个有效的语法。作为 UnmatchedTable,只是从嵌套部分返回的临时表的名称。一次又一次地运行查询会将记录添加到 Table3,因为它们是独立的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多