Oracle 中 IN 的行为
Behavior of IN in Oracle
我编写了一个子查询来连接两个 table 并获取数据,其中一个 ID 列对于两个连接是通用的。但是列名称不同,如下所示。
我写的这个:
SELECT parent_id ,name
FROM parent_table
WHERE parent_id IN (SELECT parent_id
FROM child_table
WHERE country IN ('US'));
它将父 table 中的所有行作为
子查询
SELECT parent_id FROM child_table WHERE country IN ('US')
似乎不正确。 table 中没有 parent_id 列。
以下查询正确的是:
SELECT parent_id ,name
FROM parent_table
WHERE parent_id IN (SELECT child_id
FROM child_table
WHERE country IN ('US'));
现在我的问题是:为什么第一个查询没有给出任何错误,因为子查询不正确?
隔离执行的子查询将return ORA-00904
.
子查询可能包含对外部查询 table 的引用。由于您没有限定列,并且 child_table 没有 parent_id 列,因此您的查询
SELECT parent_id ,name
FROM parent_table WHERE parent_id IN ( SELECT parent_id FROM child_table WHERE country IN ('US'));
将被评估为
SELECT parent_id ,name
FROM parent_table WHERE parent_id IN ( SELECT parent_table.parent_id FROM child_table WHERE country IN ('US'));
这将 return 所有 parent_table 行,只要 child_table 至少有一个 'US' 行。
始终限定列(当涉及多个 table 时)是一种很好的编程习惯。还可以使用 table 别名来节省一些输入。
SELECT pt.parent_id, pt.name
FROM parent_table pt WHERE pt.parent_id IN ( SELECT ct.child_id FROM child_table ct WHERE ct.country IN ('US'));
Oracle 正在使用来自外部查询的 parent_id
列。
如果您用它们引用的表限定列,那么 Oracle 正在做:
SELECT parent_table.parent_id,
parent_table.name
FROM parent_table
WHERE parent_table.parent_id IN (
SELECT parent_table.parent_id
-- ^^^^^^
FROM child_table
WHERE child_table.country IN ('US')
);
这将 return 所有行并且不会引发异常。
但你期待的是:
SELECT parent_table.parent_id,
parent_table.name
FROM parent_table
WHERE parent_table.parent_id IN (
SELECT child_table.parent_id
-- ^^^^^
FROM child_table
WHERE child_table.country IN ('US')
);
这会引发异常,因为 child_table
中没有 parent_id
列。
我编写了一个子查询来连接两个 table 并获取数据,其中一个 ID 列对于两个连接是通用的。但是列名称不同,如下所示。
我写的这个:
SELECT parent_id ,name
FROM parent_table
WHERE parent_id IN (SELECT parent_id
FROM child_table
WHERE country IN ('US'));
它将父 table 中的所有行作为
子查询
SELECT parent_id FROM child_table WHERE country IN ('US')
似乎不正确。 table 中没有 parent_id 列。
以下查询正确的是:
SELECT parent_id ,name
FROM parent_table
WHERE parent_id IN (SELECT child_id
FROM child_table
WHERE country IN ('US'));
现在我的问题是:为什么第一个查询没有给出任何错误,因为子查询不正确?
隔离执行的子查询将return ORA-00904
.
子查询可能包含对外部查询 table 的引用。由于您没有限定列,并且 child_table 没有 parent_id 列,因此您的查询
SELECT parent_id ,name
FROM parent_table WHERE parent_id IN ( SELECT parent_id FROM child_table WHERE country IN ('US'));
将被评估为
SELECT parent_id ,name
FROM parent_table WHERE parent_id IN ( SELECT parent_table.parent_id FROM child_table WHERE country IN ('US'));
这将 return 所有 parent_table 行,只要 child_table 至少有一个 'US' 行。
始终限定列(当涉及多个 table 时)是一种很好的编程习惯。还可以使用 table 别名来节省一些输入。
SELECT pt.parent_id, pt.name
FROM parent_table pt WHERE pt.parent_id IN ( SELECT ct.child_id FROM child_table ct WHERE ct.country IN ('US'));
Oracle 正在使用来自外部查询的 parent_id
列。
如果您用它们引用的表限定列,那么 Oracle 正在做:
SELECT parent_table.parent_id,
parent_table.name
FROM parent_table
WHERE parent_table.parent_id IN (
SELECT parent_table.parent_id
-- ^^^^^^
FROM child_table
WHERE child_table.country IN ('US')
);
这将 return 所有行并且不会引发异常。
但你期待的是:
SELECT parent_table.parent_id,
parent_table.name
FROM parent_table
WHERE parent_table.parent_id IN (
SELECT child_table.parent_id
-- ^^^^^
FROM child_table
WHERE child_table.country IN ('US')
);
这会引发异常,因为 child_table
中没有 parent_id
列。