【问题标题】:Find rows in A that don't have an associated row in B, where the FK is on B?在 A 中查找在 B 中没有关联行的行,而 FK 在 B 上?
【发布时间】:2011-05-31 16:09:17
【问题描述】:

我一直在做的是

SELECT * FROM a LEFT JOIN b ON b.a_id=a.id WHERE b.id IS NULL

基本上,我试图找到没有关联ba 行,其中外键存储在b 上。这是执行此操作的正确方法,还是有其他类型的连接来执行此操作?

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    您正在寻找NOT EXISTS:

    SELECT 
      * 
    FROM 
      a
    WHERE
      NOT EXISTS (SELECT 1 FROM b WHERE a_id = a.id)
    

    b.a_id 上建立索引有助于提高此查询的性能。

    【讨论】:

    • @Denis:当然不是。当b.a_id 上有索引时,这将非常快。
    • 虽然查询的格式表明 EXISTS 作为单独的查询检查每个单独的记录,但情况并非如此。优化过程能够以非常类似于传统 JOIN 的方式理解关系,因此它实际上非常有效。
    • 我认为这是更好的方法。
    • Joe 在另一个线程上发布了该链接,让我早点做一些实验。在 Postgres 上,NOT EXISTSLEFT JOIN/IS NULL 生成了相同的计划,至少在我输入的特定随机数据下。我只会根据表大小和问题的数据分布的实际测试在这些之间进行选择在眼前。 (例如,MySQL 可能有完全不同的优化。)所有其他条件相同我发现 JOIN 更容易阅读,因为它更短。
    【解决方案2】:

    是的,这是正常的方式,我不知道更好的方式。

    【讨论】:

      【解决方案3】:

      你可以试试

      Select * from a where a.id not in (Select a_id from b)
      

      【讨论】:

      • @Andrea Girardi:一方面,这应该是(select a_id from b),除此之外,如果从子查询返回的值中有NULL,这将失败。
      【解决方案4】:

      前面的三种反应都是正确的,此时我想你可以考虑一下三种查询的性能。你可以看看这个网址:

      http://rockycode.com/blog/not-vs-outer-join-performance/

      在我看来,我认为外连接是最好的方式,如果你没有太多的行,这三种方式或多或少是相等的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-20
        • 1970-01-01
        • 2011-08-10
        相关资源
        最近更新 更多