Icy*_*now 26 sql-server t-sql subquery alias
我有一个 SQL 查询,其别名与其子查询的某些别名相同。
例如:
select *
from ROOM r
where ...
(
select *
from ROAD r
where ...
)
Run Code Online (Sandbox Code Playgroud)
这很好用,因为子查询的别名似乎隐藏了主要的。
r?Con*_*lls 17
嵌套子查询可以使用与父查询中使用的别名相同的别名,但对于阅读代码的人来说可能有点混乱。嵌套子查询上别名的命名空间与父级上的命名空间是分开的。例如,下面的查询有一个嵌套的子查询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
Run Code Online (Sandbox Code Playgroud)
在相关子查询中,您可以访问父查询的别名,因此别名在父查询和相关子查询中必须是唯一的。如果我们采用如下的相关子查询,我们将在父查询和相关子查询之间共享一个单一的全局名称空间:
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)
Run Code Online (Sandbox Code Playgroud)
相关子查询没有别名,因为它不参与这样的连接1。引用b和b2forbar都可用于子查询,因为相关子查询与父查询共享它们的别名命名空间。
1请注意,优化器可能会选择在幕后的计划中使用连接运算符,尽管指定的实际操作是相关子查询,而不是针对嵌套子查询的连接。
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)
Run Code Online (Sandbox Code Playgroud)
输出为“3”:表 T 和 U 有共同的 2 和 3,但谓词WHERE进一步过滤返回 3 的行,并且 2 在 V 中不存在。