将别名与子查询一起使用时应遵循哪些规则?

What are some rules to follow when using alias names along with subqueries?

看到这两个片段后我很困惑,一个有效,另一个无效。所以有一个 table MyTable 有两列:IDValue

代码段 1(失败)

/*Find the ID that is related to the maximum value*/
SELECT ID
FROM MyTable AS t /*Here MyTable can be a complex subquery. MyTable is just a placeholder here to show you can't use alias t in the subquery after WHERE*/
WHERE Value = (SELECT MAX(Value) FROM t) /*Get error here: 'Invalid object name t"*/

片段 2(有效)

/*Rank Value column*/
SELECT ID, Value,
(SELECT COUNT(Value) FROM MyTable WHERE Value >= t.Value) AS Rank /*No error raised here for t.Value*/
FROM MyTable AS t

This post 解释说

One cannot reference an alias from a subquery at the same scope

但是 the same scope 是什么?它能解释为什么片段 2 有效吗?我假设还有其他可能的方式在不同的位置使用别名和子查询(比如在不同的子句中或以不同的方式嵌套)。那么在对子查询使用别名时,是否有任何通用的防错规则可遵循?

(请不要使用类似视图的技巧,例如 CTE 或变通方法,例如 TOP 和 LIMIT)

您的第一个查询应该有效:

SELECT ID
FROM <tablename> t
WHERE Value = (SELECT MAX(Value) FROM <tablename>) ;

您不能再次使用别名来引用整个 table(我认为您是这样做的,但是 table 和别名在 t实际例子)。

相反,别名用于引用 table 中的 。这允许您将列与正确的 table 相关联 - 因此查询明确地执行您想要的。

让我们看看第一个查询。

SELECT ID
FROM MyTable AS t
WHERE Value = (SELECT MAX(Value) FROM t)

这将尝试从 table 别名 t.select。
这是不允许的。它应该 select 来自 table 或视图。

例如:

SELECT ID
FROM MyTable AS t
WHERE Value = (SELECT MAX(Value) FROM MyTable)

请注意,这与范围无关。 不使用任何子查询也是不允许的。

例如,这会因同样的原因而失败

SELECT t1.*, t2.*
FROM MyTable AS t1
JOIN t1 AS t2 ON t2.id = t1.id

接下来是第二个查询

SELECT ID, Value,
( 
    SELECT COUNT(Value) 
    FROM MyTable t1sub
    WHERE t1sub.Value >= t1out.Value
) AS Rank
FROM MyTable AS t1out

这称为相关子查询。
该子查询通过 t1sub.Value 将外部查询的当前 t1out.Value 链接到子查询中的 table。

它为外部查询的每一行重新执行子查询。

关于范围。
这是关于 SQL 的一部分可以查看和使用的内容。

在前面的SQL中,t1sub别名只在相关子查询范围内已知。
外部查询甚至不知道子查询中使用的别名 t1sub
在相关子查询中,可以看到和使用 t1out.Value

一些测试可以在 db<>fiddle here

上找到