子查询的别名与主查询的别名相同

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)

这很好用,因为子查询的别名似乎隐藏了主要的。

  1. 它会在所有情况下都这样工作吗?
  2. 我会得到未定义的结果吗?
  3. 如果可以这样做,我如何引用主查询的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。引用bb2forbar都可用于子查询,因为相关子查询与父查询共享它们的别名命名空间。


1请注意,优化器可能会选择在幕后的计划中使用连接运算符,尽管指定的实际操作是相关子查询,而不是针对嵌套子查询的连接。


sla*_*man 5

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 中不存在。