将别名与子查询一起使用时应遵循哪些规则?
What are some rules to follow when using alias names along with subqueries?
看到这两个片段后我很困惑,一个有效,另一个无效。所以有一个 table MyTable
有两列:ID
和 Value
代码段 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
上找到
看到这两个片段后我很困惑,一个有效,另一个无效。所以有一个 table MyTable
有两列:ID
和 Value
代码段 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
上找到