sql - 使用别名和子查询时要遵循哪些规则?
问题描述
看到这两个片段后我很困惑,一个有效,另一个无效。所以有一个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
这篇文章解释说
不能从同一范围内的子查询中引用别名
但什么是the same scope
?它解释了为什么片段 2 有效吗?我假设还有其他可能的方法可以在不同的位置使用别名和子查询(例如在不同的子句中或以不同的方式嵌套)。那么在使用带有子查询的别名时,是否有任何通用的防错规则要遵循?
(请不要使用 CTE 等类似视图的技巧或 TOP 和 LIMIT 等变通方法)
解决方案
让我们看看第一个查询。
SELECT ID
FROM MyTable AS t
WHERE Value = (SELECT MAX(Value) FROM t)
这将尝试从表中选择别名t
。
这是不允许的。它应该从表或视图中选择。
例如:
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
子查询中的表。
它为外部查询中的每一行重新执行子查询。
关于范围。
它是关于 SQL 的一部分可以查看和使用的内容。
在前面的 SQL 中,t1sub
别名只在相关子查询的范围内是已知的。
外部查询甚至不知道t1sub
子查询中使用的别名。
在相关子查询中,t1out.Value
可以看到和使用。
可以在db<>fiddle here上找到一些测试
推荐阅读
- c# - 以编程方式在实时图表中显示工具提示
- parsing - Rebo/Red parse:是否可以在嵌入嵌套 div 的两个标记之间复制
- apache-spark - 在 Kubernetes 上运行 Spark2.3,远程依赖 S3
- reactjs - Dockerfile - npm:未找到
- angular - Instagram 照片提要 Angular 5
- uml - 什么是统一建模语言中的刻板印象?
- python - Python重新解析文件
- postgresql - Symfony3.4:Postgis,学说模式错误
- android - 由于 gradle 错误,无法启动新项目
- php - Laravel - 具有关系的多表插入