选择*不存在


94

我想我要沿着这条路走正确的路...请忍受,因为我的SQL并不是最出色的

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

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

因此,基本上我有一张桌子,上面列出了员工及其详细信息。然后是另一个表,其中包含一些其他详细信息,包括其名称。在eotm_dyn表中没有名称的地方,这意味着它们没有条目,我想确切地知道他们是谁,或者换句话说,确切地知道缺少什么。

上面的查询没有返回任何内容,但是我知道缺少20个名字,所以我显然没有正确。

有人可以帮忙吗?

Answers:


160

您没有在查询中加入表。

除非原始查询没有任何记录,否则原始查询将始终不返回任何内容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


30
一年两次,我需要“不存在”,而我总是忘记如何正确使用它。谢谢-此示例现在将添加为书签。
Mateng 2012年

1
有人可以为“ LEFT JOIN + NULL过滤器不如NOT EXISTS效率低”提供参考吗?显而易见,但是我从未在文档中看到过。谢谢。
toni07 2015年

2
@ toni07实际上,这是一个传说。左联接获胜。explainextended.com/2009/09/18/... .. Quassnoi的博客始终是一个有用的资源。
Kaii 2016年

我将如何在HAVING子句中使用它?akagroup by X having exist [row with employeeID = e.id]
phil294 '16

@blauhirn:就是这样
Quassnoi

83
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

1
注意!NOT IN如果namenull值,则无法按预期工作。在36分钟20秒的视频中观看SESSION:每个SQL程序员都应该知道的10种查询调优技术(Kevin Kline,Aaron Bertrand)
hlovdal

12

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

例:

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

7
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。然而,在大多数情况下,优化器通常将对它们进行相同处理。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.