我在查询中两次使用相同的别名 (RankedPrice)。我预计这会导致错误。但它运作良好。为什么会这样?我原以为它会抛出像 C++ 或 Java 这样的变量范围错误,但它没有发生。
select *
from
(select *, RANK() over(order by retailprice) as RankedPrice
from CurrentProducts) as RankedPrice
where RankedPrice = 5
由于 SQL 的工作方式,您永远不会对在任何特定引用中引用的对象类型有任何混淆。
如果您有SELECT a, ...
,您就知道这a
是对列的引用。它不能是对表、数据库、存储过程、UDF 等的引用。(*)
如果您有SELECT a.b, ...
,则您知道这a
是对表的引用(+),并且b
是对列的引用。(*)
因此,没有逻辑上的理由来排除一个表包含一个表和列具有相同名称的列。
(*) - 这适用于SELECT
条款。在FROM
子句中,单部分名称只能是表(+),两部分名称只能是模式+表等。但是在每个子句中,所引用的对象类型始终是明确的。
(+) - 好吧,我在这里真正的意思是一个行源 - 一个表、一个视图、一个 CTE。如果您愿意,可以将其构造为表并在查询中使用它。
正如其他人所说,在子查询中引入相同的别名也没有障碍。但这在这里没有发生,因为我们最终得到了一个可以(正确)被引用为RankedPrice.RankedPrice
.
父查询和嵌套子查询具有不同的别名命名空间。因此嵌套子查询使用相同的别名是可以的,但是对于阅读代码的人来说可能有点混乱。
您的代码RankedPrice
中所说的首先用作列别名,然后用作派生表别名,尽管前面提到的命名空间分隔可以防止任何冲突。
我还应该指出,相关子查询有一个共享命名空间。