首页 > 解决方案 > 为什么我能够从子查询中引用外部查询列?

问题描述

我希望如果我编写一个子查询,那么主查询中可用的列在子查询中将不可用。情况似乎并非如此,我不明白为什么。

采取以下示例表和查询:

CREATE TABLE test_1 (
    col_a TEXT
);

CREATE TABLE test_2 (
    col_b TEXT
);

INSERT INTO test_1
VALUES
    ('Bob'),
    ('Tim')
;

INSERT INTO test_2
VALUES
    ('Sam'),
    ('Tim')
;

SELECT
    col_a
FROM
    test_1
WHERE col_a IN (SELECT col_a FROM test_2);

在子查询中SELECT col_a FROM test_2,我希望得到一个错误,因为col_a在 table 中不存在test_2。相反,子查询返回col_afrom的内容table_1

我得到的输出是:

 col_a
-------
 Bob
 Tim

我正在运行以下版本的 PostgreSQL:

PostgreSQL 9.5.13 on x86_64-pc-linux-gnu

标签: sqlpostgresql

解决方案


当您在查询中有多个表时,请始终使用限定的表名。您认为查询正在执行:

SELECT t1.col_a
FROM test_1 t1
WHERE t1.col_a IN (SELECT t2.col_a FROM test_2 t2);

这会产生错误,因为t2.col_a不存在。

但是,子查询的范围规则说,如果列不在子查询中,则在外部查询中查找。因此,如果t2.col_a不存在,则查询变为:

SELECT t1.col_a
FROM test_1 t1
WHERE t1.col_a IN (SELECT t1.col_a FROM test_2 t2);

解决方案是限定所有列引用,这样就不会有歧义。


推荐阅读