1  /  1  页   1 跳转 查看:2260

[技术文档] 子查询里的列名匹配

子查询里的列名匹配

子查询里的列名匹配


--王成辉翻译整理,转帖请注明出自微软BI开拓者www.windbi.com
--原帖地址


子查询里的列匹配有点特殊。如果你曾经遇到过的话,那么可能不会犯第二次错了。现在让我们花点时间来研究一下。

有个表叫users,为了简便,只列出一部分必须的列:


CREATE TABLE dbo.Users

(
  UserID INT PRIMARY KEY,
  -- ... other columns ...
);

针对这个表,要选出特定的一些用户出来,具体的代码简单如下:
DECLARE @u TABLE (id INT PRIMARY KEY);

INSERT @u(id) SELECT 1 UNION ALL SELECT 2;

SELECT UserID FROM dbo.Users
  WHERE UserID IN (SELECT
UserID FROM @u);

请注意子查询里的列是userid,而不是id。运行这个查询,居然得到了源表的全部用户。为什么啊?大部分情况下不会有任何影响,但在子查询里,如果在引用的对象上找到不列,编译器就会试着在父查询里来绑定那列。如果没有找到的话,就会得到一个错误(非法的列名);如果找到了多个的话,会得到另一个错误(列名不明确)。但当正好有一个的时候,上面的查询就可以重写成下面的语句:


SELECT UserID FROM dbo.Users
  WHERE UserID IN (SELECT UserID FROM dbo.Users);

-- which of course becomes:

SELECT UserID FROM dbo.Users;

注意如果@u没有记录的话,外层的查询也会没有记录返回。但如果只要子查询里有一条记录,那么外层查询就会返回所有的记录。这种错误很难诊断,所以一定要小心。
虽有智慧,不如乘势;虽有鎡基,不如待时。
君子学以聚之,问以辨之,宽以居之,仁以行之。
独学而无友,则孤陋而寡闻。
 

回复:子查询里的列名匹配

是不是叫聪明反被聪明误
 

回复:子查询里的列名匹配

Studying
 
1  /  1  页   1 跳转

版权所有 微软BI开拓者 

Powered by Discuz!NT 2.1.202    Copyright © 2001-2012 Comsenz Inc.
Processed in 0.0625 second(s) , 3 queries.
返顶部