“NOT IN table.col”和“NOT IN SELECT col FROM FROM”之间的区别

时间:2015-01-13 22:15:16

标签: sql oracle

一个非常基本的问题。但

之间有什么区别
SELECT t.col
FROM table t, other_table o
WHERE t.col NOT IN o.col

SELECT col
FROM table
WHERE col NOT IN (SELECT col FROM other_table)

在语义上这听起来与我相当,但第一个创建重复。我理解错了什么?

2 个答案:

答案 0 :(得分:2)

第一个甚至不会在大多数RDBMS中运行,但是在oracle中它返回除t.col = o.col之外的每个记录组合,如果你添加了{{1},你会看到这个到你的o.col

后一个查询会返回SELECT中未与table中的任何记录共享col值的记录。

最好通过示例说明:

表1

other_table

表2

| ANIMAL |
|--------|
|    dog |
|    cat |
|  horse |

查询:

| ANIMAL |
|--------|
|    dog |
|   fish |

演示:SQL Fiddle

基本上,您在第一个查询中有一个笛卡尔积,它会返回两个表中的每个记录组合,但您的SELECT t."animal",o."animal" FROM Table1 t, Table2 o WHERE t."animal" NOT IN o."animal" | ANIMAL | ANIMAL2 | |--------|---------| | cat | dog | | horse | dog | | dog | fish | | cat | fish | | horse | fish | SELECT t."animal" FROM Table1 t WHERE t."animal" NOT IN (SELECT o."animal" FROM Table2 o) | ANIMAL | |--------| | horse | | cat | 条件会过滤掉其中一个。第二个查询没有WHERE,隐式/显式,它只是从一个表中获取记录,并根据从另一个表中绘制的条件进行过滤。

答案 1 :(得分:1)

据我所知,查询(稍加修改):

SELECT t.col
FROM table t, other_table o
WHERE t.col <> o.col

生成笛卡尔积,然后过滤它。

以下示例可能不是发生的确切过程,但它可能会给出情况的抽象概述。

如果在表table中,您将拥有以下行:

col
----
A
B

并且在表other_table中会有:

col
---
B
E

两个表查询的笛卡尔积(FROM table t, other_table o)可能是:

table.col     other_table.col
---------------------------
A             B
A             E
B             B
B             E 

然后,应用上面的WHERE t.col <> o.col子句将被过滤,给出结果

table.col     other_table.col
---------------------------
A             B
A             E
B             E 

由于在查询结果集中,只为输出选择了table.col,因此最终结果包含A值重复:

table.col
---------
A        
A        
B        

我希望它可以帮到你某种方式。

#UPDATE

至于查询:

SELECT col
FROM table
WHERE col NOT IN (SELECT col FROM other_table)

由于没有连接,因此在构建结果时只考虑table表中的行集。 据我所知,条件WHERE col NOT IN (SELECT col FROM other_table)针对table中的每一行进行评估。 检查列table.col是否属于从other_table获取数据的子查询返回的结果集。如果它验证为TRUE,那么,它被带入结果集,如果没有,它被排除在它之外。

总结一下,我认为第一个查询只会将table.col值加倍,因为准备阶段将表连接(合并)在一起,因此第二个查询仅从结果集中获取来自{的记录{1}}仅将table用于验证目的。这与查询结构有关 - 如果我当然是对的。