【问题标题】:How do I correctly use two Not Exists statements in a where clause using Access SQL VBA?如何使用 Access SQL VBA 在 where 子句中正确使用两个 Not Exists 语句?
【发布时间】:2011-02-03 13:20:42
【问题描述】:

我有 3 个表:NotHeard、analyzed、analyzed2。在这些表中的每一个中,我都有名为 UnitID 和 Address 的两列。

我现在要做的是从 NotHeard 中为 UnitID 和 Address 列选择所有未出现在已分析或已分析2中的记录。我创建的SQL语句如下:

SELECT UnitID, Address  
INTO [NotHeardByEither] 
FROM [NotHeard] 
Where NOT EXISTS( Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
or NOT EXISTS( Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
Group BY UnitID, Address 

我认为这会起作用,因为我使用了单个 NOT EXISTS 子查询行,并且过去它对我来说工作得很好。然而,上面的查询返回的数据与 NotHeard 表中的数据相同,而如果我取出 or NOT EXISTS 部分,它可以正常工作。

关于我做错了什么或如何做我想做的任何想法?

【问题讨论】:

    标签: sql vba ms-access-2007 not-exists


    【解决方案1】:

    看起来您想要左连接。我的 Access 语法可能有点偏离。

    SELECT UnitID, Address  
    INTO [NotHeardByEither] 
    FROM [NotHeard] 
        LEFT JOIN [analyzed] ON [NotHeard].UnitID = [analyzed].UnitID
        LEFT JOIN [analyzed2] ON [NotHeard].UnitID = [analyzed2].UnitID
    WHERE IsNull([analyzed].UnitID)
        AND IsNull([analyzed2].UnitID)
    Group BY UnitID, Address 
    

    【讨论】:

    • 我似乎无法完成这项工作,我不断收到左连接周围的运行时错误
    • 在访问中使用可视化查询生成器 :)
    • 哈哈,没想到。我已经习惯了自己输入它们,我忘记了它的存在。
    • 哇,好受虐狂。为什么有人想要输入比他们必须输入的更多的 SQL?
    • 因为它们是用于 VBA 代码的。我只是在其中输入它们,因为它们中的大多数在更改名称之前我都做过类似的事情,所以我复制、粘贴然后进行更改。
    【解决方案2】:

    关于你原来的查询,试试

    NOT (
       EXISTS( 
        Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
    AND EXISTS( 
        Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
        )
    

    这意味着两者都没有。但这等于您最初的(在样本数据上测试)。你确定你不是说不在A也不在B吗?那是

    NOT (
       EXISTS( 
        Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
    OR EXISTS( 
        Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
        )
    

    请意识到 EXISTS 解决方案正在使用相关子查询,其性能可能比 LEFT JOIN 和 NULL 更差,这是一个示例。

    SELECT NotHeard.UnitID, NotHeard.Address
    FROM (NotHeard LEFT JOIN analyzed ON NotHeard.UnitID = analyzed.UnitID) 
         LEFT JOIN analyzed2 ON NotHeard.UnitID = analyzed2.UnitID
    WHERE analyzed.UnitID Is Null OR analyzed2.UnitID Is Null
    GROUP BY NotHeard.UnitID, NotHeard.Address;
    

    请注意,与 Austin 的解决方案相比,我在条件中使用了 OR,AND 既不会给你分析,也不会给你分析2。

    【讨论】:

    • 此外,当使用 NOT 关键字时,Jet/ACE 对所有子查询(无论是否相关)进行了不良优化。由于某些原因,当涉及 NOT 时,您不能依赖引擎使用比较两侧的索引。我不知道为什么会这样,但我已经看过很多次了。不幸的是,Jet SHOWPLAN 没有解释它的子查询优化(它从未在 SHOWPLAN 中实现)。
    猜你喜欢
    • 2012-05-16
    • 2013-04-17
    • 2019-05-18
    • 2013-10-30
    • 1970-01-01
    • 2020-01-28
    • 2021-12-24
    • 2016-01-09
    • 2018-01-28
    相关资源
    最近更新 更多