相关子查询:解析不明确的名称

Man*_*ngo 2 subquery

假设我有 2 个共享一些列名的表。在这种情况下,主键是两个都被调用id

CREATE TABLE artists(
    id int primary key,
    name text,
--  …,

);
CREATE TABLE paintings(
    id int primary key,
    artistid references artists(id),
    title text,
--  …,
);
Run Code Online (Sandbox Code Playgroud)

注意: 我知道有一些反对将主键称为通用名称id的论据,例如,但让我们假设,为了争论,它超出了我的控制范围。无论如何,就这个问题而言,它可能是任何其他列。

假设我现在有一个粗心编写的SELECT语句,它试图使用相关子查询从引用的表中提取数据:

SELECT
    id, title,
    (SELECT name FROM artists WHERE artistid=id) as artist
FROM paintings;
Run Code Online (Sandbox Code Playgroud)

显然,内部WHERE子句可以更好地写成WHERE paintings.artistid=artists.id. 但是我已经摆脱了它并且它有效。如果我将WHERE子句写为id=artistid.

我知道这不是最好的方法,但我更惊讶的是它理解了我的意图,这不是我们对 SQL 的期望。

问题是:SQL 如何解释相关子查询中的歧义列?

Mar*_*ith 6

它按作用域顺序解析列名。artists如果存在这样的歧义,子查询中的列将根据表中的列进行解析。

这有时非常有用,也可能非常危险

我通常使用表别名和两个部分名称来避免任何意外问题,并使读者更清楚每列来自哪个表。

SELECT p.id,
       p.title,
       (SELECT a.name
        FROM   artists a
        WHERE  p.artistid = a.id) AS artist
FROM   paintings p; 
Run Code Online (Sandbox Code Playgroud)