这是一个关于 t-sql 如何决定哪个“列”在子查询范围内的文档的问题。我尝试谷歌搜索,结果出现this link但它没有解释它。
这是一个可运行的示例。 update
语句将 #a.a
中的唯一条目设置为 null
。据推测,这是因为对别名 a
的子查询引用解析为表 #b
,该表没有与值 1
匹配的行,因此返回 null
到外部 update
查询。
if object_id('tempdb..#a') is not null
drop table #a
if object_id('tempdb..#b') is not null
drop table #b
create table #a (a int)
create table #b (a int)
insert into #a values (1)
insert into #b values (2)
update a
set a = (select a from #b as a where a.a = 1)
from #a as a
是否有文档表明这种设计选择?否则它是不明确的,因为如果我更改更新语句以使用不同的别名,则 #a.a
中的最终值是 2
:
update aa
set a = (select a from #b as a where aa.a = 1)
from #a as aa
最佳答案
This引用文献可能会更好地解释它。
这个想法很简单。表别名被解释为“第一个”表定义,从子查询的当前级别开始,然后向外移动。子查询中的表别名不能在外部查询中使用,因此引用只能“向内”移动。
在您的示例中:
update a
set a = (select a from #b as a where a.a = 1)
from #a as a
a.a
引用表 a
的列 a
。在子查询本身中,表a
定义为#b
。这就是引用。
在此查询中:
update aa
set a = (select a from #b as a where aa.a = 1)
from #a as aa;
表别名是aa
。这在子查询中没有定义。它是在下一级定义的,因此它引用#a
。
一般来说,不要在查询中为不同的表指定相同的别名(子查询上的别名除外,本质上只是特定表的过滤/选择版本)。这只会导致困惑。
关于sql - transact sql 如何知道我在这个子查询中引用哪个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21419737/