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

时间:2019-03-16 21:53:38

标签: sql subquery alias

看到这两个摘要后,我很困惑,一个起作用了,另一个却没有。因此,有一个表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帖子对此进行了解释

  

一个人不能从相同范围的子查询中引用别名

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

(请不要使用类似CTE之类的视图技巧或诸如TOP和LIMIT之类的解决方法)

2 个答案:

答案 0 :(得分:1)

您的第一个查询应该可以工作:

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

您不能使用别名再次引用整个表(这是我认为您要执行的操作,但是在实际示例中,表和别名是t)。

相反,别名用于表中的。这样,您就可以将列与正确的表相关联-这样查询就可以明确地实现您的预​​期。

答案 1 :(得分:1)

让我们看一下第一个查询。

<div class="container">
  <div id='div1'></div>
  <div id='div2'></div>
  <div id='div3'></div>
  <div id='div4'></div>
</div>

这将尝试从表别名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

这称为相关子查询。
该子查询通过t1sub.Value将外部查询的当前SELECT ID, Value, ( SELECT COUNT(Value) FROM MyTable t1sub WHERE t1sub.Value >= t1out.Value ) AS Rank FROM MyTable AS t1out 链接到子查询中的表。

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

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

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

可以在 db <>小提琴here

上找到一些测试