【问题标题】:SELECT * WHERE NOT EXISTS选择 * 不存在的地方
【发布时间】:2010-10-29 06:36:27
【问题描述】:

我认为我正在走正确的道路...请耐心等待,因为我的 SQL 不是最好的

我正在尝试查询数据库以从一个表中选择某些单元格不存在于另一个表中的所有内容。这么多没有多大意义,但我希望这段代码能

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

所以基本上我有一张桌子,上面列出了员工及其详细信息。然后是另一个包含一些其他详细信息的表,包括他们的名字。如果 eotm_dyn 表中没有名称,这意味着他们没有条目,我想看看他们到底是谁,或者换句话说,看看到底缺少什么。

上面的查询什么也没返回,但我知道有 20 个名字不见了,所以我显然没弄对。

谁能帮忙?

【问题讨论】:

    标签: mysql not-exists


    【解决方案1】:

    您没有在查询中加入表。

    除非eotm_dyn 中根本没有记录,否则您的原始查询将始终不返回任何内容,在这种情况下它将返回所有内容。

    假设这些表应该在employeeID 上连接,请使用以下命令:

    SELECT  *
    FROM    employees e
    WHERE   NOT EXISTS
            (
            SELECT  null 
            FROM    eotm_dyn d
            WHERE   d.employeeID = e.id
            )
    

    您可以使用LEFT JOIN 关键字连接这些表并过滤掉NULL,但这可能比使用NOT EXISTS 效率低。

    【讨论】:

    • 我每年需要两次“WHERE NOT EXISTS”,但我总是忘记如何准确地使用它。谢谢 - 这个例子现在将被加入书签。
    • 有人可以为“LEFT JOIN + NULL 过滤器的效率低于 NOT EXISTS”提供参考吗?这很明显,但我从未在文档中看到过。谢谢。
    • @toni07 其实那是个传说。左连接获胜。 explainextended.com/2009/09/18/… .. Quassnoi 的博客总是有用的资源。
    • 如何在 HAVING 子句中使用它?又名group by X having exist [row with employeeID = e.id]
    • @blauhirn:就这样
    【解决方案2】:

    您也可以查看this related question。该用户报告说,使用连接比使用子查询提供了更好的性能。

    【讨论】:

      【解决方案3】:
      SELECT * from employees
      WHERE NOT EXISTS (SELECT name FROM eotm_dyn)
      

      除非eotm_dyn 为空,否则从不返回任何记录。您需要对SELECT name FROM eotm_dyn 设置某种标准,例如

      SELECT * from employees
      WHERE NOT EXISTS (
          SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
      )
      

      假设这两个表是通过外键关系链接的。此时,您可以使用各种其他选项,包括 LEFT JOIN。然而,在大多数情况下,优化器通常会以相同的方式处理它们。

      【讨论】:

        【解决方案4】:
        SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)
        

        SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)
        

        SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL
        

        【讨论】:

        【解决方案5】:

        您可以执行 LEFT JOIN 并断言连接的列为 NULL。

        例子:

        SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
        

        【讨论】:

          猜你喜欢
          • 2016-07-16
          • 2016-05-20
          • 1970-01-01
          • 2020-10-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-24
          相关资源
          最近更新 更多