我偶然发现了这个例子:
SELECT SupplierName
FROM Suppliers
WHERE EXISTS (SELECT ProductName FROM Products WHERE Products.SupplierID = Suppliers.supplierID );
它工作起来没有问题,并显示了请求的行,但是当我尝试将子查询作为如下查询运行时
SELECT ProductName FROM Products WHERE Products.SupplierID = Suppliers.supplierID ;
它告诉我Suppliers.SupplierID是一个未知列,我遗漏了什么?
您认为查询是:
SELECT s.SupplierName
FROM Suppliers s
WHERE EXISTS (SELECT p.ProductName
FROM Products p
WHERE p.SupplierID = s.supplierID
);
但如果p.ProductName
不存在,则SQL将伸向外部查询,并将其解释为:
SELECT s.SupplierName
FROM Suppliers s
WHERE EXISTS (SELECT s.ProductName
FROM Products p
WHERE p.SupplierID = s.supplierID
);
在这种情况下,它没有任何区别,因为exists
只检查行的存在,而不检查列的存在。 我通常使用select1
来编写。
话虽如此,但它在其他情况下也能发挥作用。 因此,这一寓意仍然适用:
寓意:始终限定所有列引用,特别是在有多个表引用的查询中。