"NOT IN table.col" 和 "NOT IN SELECT col FROM table" 之间的区别
Difference between "NOT IN table.col" and "NOT IN SELECT col FROM table"
一个非常基本的问题。但是
有什么区别
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)
从语义上讲,这对我来说非常相似,但第一个创建了重复项。我哪里理解错了?
第一个在大多数 RDBMS 中甚至不会 运行,但在 oracle 中它 return 记录的每个组合,除了 t.col
= o.col
,你如果您将 o.col
添加到您的 SELECT
,就会看到这个
后者查询 table
中的 returns 条记录,这些记录不与 other_table
中的任何记录共享 col
值。
最佳示例:
表 1
| ANIMAL |
|--------|
| dog |
| cat |
| horse |
表 2
| ANIMAL |
|--------|
| dog |
| fish |
查询:
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 |
演示:SQL Fiddle
基本上,您在第一个查询中得到了一个笛卡尔积,它将 return 来自两个 table 的记录的每个组合,但是您的 WHERE
条件过滤掉了一个他们中的。第二个查询没有 JOIN
、implicit/explicit,它只是从一个 table 中获取记录并根据恰好从另一个 table 中提取的条件进行过滤。
据我所知,查询(稍作修改):
SELECT t.col
FROM table t, other_table o
WHERE t.col <> o.col
生成笛卡尔积,然后对其进行过滤。
下面的示例可能不是发生的确切过程,但它可能提供了对情况的抽象概述。
如果在 table table
中,您将有以下行:
col
----
A
B
并且在 table other_table
中会有:
col
---
B
E
两个 table 查询的 笛卡尔积 (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
希望对您有所帮助。
#更新
至于查询:
SELECT col
FROM table
WHERE col NOT IN (SELECT col FROM other_table)
由于没有连接,因此在构建结果时只考虑 table
table 中的行集。
据我了解,条件 WHERE col NOT IN (SELECT col FROM other_table)
是针对 table
中的每一行进行评估的。
检查列table.col
是否属于从other_table
取数据的子查询返回的结果集。如果它验证为 TRUE,则将其纳入结果集中,否则,将其排除在外。
总结一下,我认为第一个查询使 table.col
值加倍只是因为准备阶段,其中 tables 连接(合并)在一起,因此第二个查询需要结果集仅记录来自 table
使用 other_table
仅用于验证目的。这与查询结构有关——当然如果我是对的。
一个非常基本的问题。但是
有什么区别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)
从语义上讲,这对我来说非常相似,但第一个创建了重复项。我哪里理解错了?
第一个在大多数 RDBMS 中甚至不会 运行,但在 oracle 中它 return 记录的每个组合,除了 t.col
= o.col
,你如果您将 o.col
添加到您的 SELECT
后者查询 table
中的 returns 条记录,这些记录不与 other_table
中的任何记录共享 col
值。
最佳示例:
表 1
| ANIMAL |
|--------|
| dog |
| cat |
| horse |
表 2
| ANIMAL |
|--------|
| dog |
| fish |
查询:
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 |
演示:SQL Fiddle
基本上,您在第一个查询中得到了一个笛卡尔积,它将 return 来自两个 table 的记录的每个组合,但是您的 WHERE
条件过滤掉了一个他们中的。第二个查询没有 JOIN
、implicit/explicit,它只是从一个 table 中获取记录并根据恰好从另一个 table 中提取的条件进行过滤。
据我所知,查询(稍作修改):
SELECT t.col
FROM table t, other_table o
WHERE t.col <> o.col
生成笛卡尔积,然后对其进行过滤。
下面的示例可能不是发生的确切过程,但它可能提供了对情况的抽象概述。
如果在 table table
中,您将有以下行:
col
----
A
B
并且在 table other_table
中会有:
col
---
B
E
两个 table 查询的 笛卡尔积 (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
希望对您有所帮助。
#更新
至于查询:
SELECT col
FROM table
WHERE col NOT IN (SELECT col FROM other_table)
由于没有连接,因此在构建结果时只考虑 table
table 中的行集。
据我了解,条件 WHERE col NOT IN (SELECT col FROM other_table)
是针对 table
中的每一行进行评估的。
检查列table.col
是否属于从other_table
取数据的子查询返回的结果集。如果它验证为 TRUE,则将其纳入结果集中,否则,将其排除在外。
总结一下,我认为第一个查询使 table.col
值加倍只是因为准备阶段,其中 tables 连接(合并)在一起,因此第二个查询需要结果集仅记录来自 table
使用 other_table
仅用于验证目的。这与查询结构有关——当然如果我是对的。