Answers:
嵌套的子查询使用与父查询相同的别名是可以的,尽管对于阅读代码的人来说可能会有些混乱。嵌套子查询上别名的名称空间与父项上的名称空间是分开的。例如,下面的查询具有一个嵌套的子查询b
,该子查询中也b
使用了别名。这可能会使程序员感到困惑,但使用DBMS引擎可以:
select a.foo
,b.bar
,b.BarCount
from (select b.bar
,count (*) as BarCount
from BarTable b
join OtherTable o
on b.OtherTableID = o.OtherTableID
group by b.bar) b
join Foobar a
on a.bar = b.bar
在关联的子查询上,您可以访问父代的别名,因此别名在父查询和关联的子查询中必须是唯一的。如果我们采用一个相关的子查询(例如下面的查询),则在父查询和相关的子查询之间共享一个全局名称空间:
select a.foo
,b.bar
from Foobar a
join Bar b
on b.FooBarID = a.FooBarID
where not exists
(select 1
from Bar b2
where b2.BarCategoryID = b.BarCategoryID
and b2.BarDate > b.BarDate)
相关子查询没有别名,因为它不参与这样的联接1。子查询可以使用引用b
和b2
,bar
因为相关子查询与父级共享别名的名称空间。
1请注意,尽管指定的实际操作是相关子查询,而不是针对嵌套子查询的联接,但优化器可能会选择在幕后的计划内使用联接运算符。
SELECT * FROM ( SELECT c FROM T ) AS T2;
-没有联接,没有关联,但是SQL标准要求为派生表分配一个范围变量(T2
在这种情况下)。
在ConcernedOfTunbridgeWells上,您要编写(强调我的意思):“在相关子查询上,您可以访问父级的别名,因此别名在父级查询和相关子查询中必须是唯一的。”
我不认为需要唯一性。我相信,如果在关联子查询中使用别名作为关联名称,以及在外部查询中使用表别名,则子查询中的别名将优先。
例:
CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)
INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)
SELECT
T1.A
FROM
#T AS T1
INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)
输出为“ 3”:表T和U共有2和3,但是WHERE
谓词进一步过滤返回到3的行,并且V中不存在2。