一个非常基本的问题。但
之间有什么区别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)
在语义上这听起来与我相当,但第一个创建重复。我理解错了什么?
答案 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
用于验证目的。这与查询结构有关 - 如果我当然是对的。