Sql 如果表在FROM子句中多次出现,为什么需要不同的表别名?

Sql 如果表在FROM子句中多次出现,为什么需要不同的表别名?,sql,join,Sql,Join,目前我正在阅读一本关于SQL的书,书中提供了以下解释: 您需要为分支表的每个实例指定一个不同的别名,以便服务器知道您在各个子句中引用的是哪个别名 但是我不明白为什么在使用不同的子句时不能从完全相同的表中连接列?为什么服务器需要创建表的第二个实例,然后将它们彼此区分开来?以便解析器在引用JOIN子句中的列时知道您所引用的表: SELECT * FROM Person // child INNER JOIN Person // parent ON Person.ID = P

目前我正在阅读一本关于SQL的书,书中提供了以下解释:

您需要为分支表的每个实例指定一个不同的别名,以便服务器知道您在各个子句中引用的是哪个别名


但是我不明白为什么在使用不同的
子句时不能从完全相同的表中
连接
列?为什么服务器需要创建表的第二个实例,然后将它们彼此区分开来?

以便解析器在引用JOIN子句中的列时知道您所引用的表:

SELECT * FROM Person      // child
INNER JOIN Person         // parent
ON Person.ID = Person.ParentID          // which table goes with which column?
或者在联接中使用其他列时:

SELECT * FROM Person      // child
INNER JOIN Person         // parent
ON Person.ID = Person.ParentID          // which table goes with which column?
    AND Person.Name = "John"  // child or parent?
或者在WHERE子句中

SELECT * FROM Person      // child
INNER JOIN Person         // parent
ON Person.ID = Person.ParentID
WHERE Name = "John"       // child or parent?
或者在添加第三个表时

SELECT * FROM Person      // child
INNER JOIN Person         // parent
ON Person.ID = Person.ParentID
INNER JOIN Address
ON Person.AddressID = Address.AddressID  // child or parent?
或者在结果中指定列时:

SELECT Name    // Child or Parent?
FROM Person      // child
INNER JOIN Person         // parent
ON Person.ID = Person.ParentID          // which table goes with which column?
底线-有太多的地方无法假定上下文,因此需要别名

SELECT * 
FROM Person AS Child
INNER JOIN Person AS Parent
ON Parent.ID = Child.ParentID          

请注意,您没有“创建[a]第二个实例”,只是引用同一个表两次。这可能是你的意思,但我想确保你明白,没有数据被复制或复制;您只是引用了一个表本身。

可以多次将
连接到一个表,但您需要在查询中对它们进行不同的命名,以便服务器知道从哪个连接获取结果。在某些情况下,解析器可能会理解您正在连接两个表,因此ID=ID上的
可以工作。然而,ID=ParentID上的
仍然是不明确的,使用附加表(同一个表或另一个列名称相同的表)的查询也是不明确的。此外,非常复杂的查询中的错误会导致混淆,并且会出现“解析器是否理解我的意图?”的问题,因此,坚持允许简单地解决这些问题的语法对每个人都有好处。我看不出您示例的第三行有任何问题。假设
ID=ParentID
等同于
Person.ID=Person.ParentID
。添加了更多的示例。可能是您误解了,也可能是本书完全错误-加入表不会创建任何表的临时副本。它可能会创建一些临时数据以提高查找性能,但无论您是否被迫使用别名,这都是正确的。@D Stanley我需要考虑一下您的示例,然后我将给出示例。非常感谢您的详细回复。我理解你的例子。我可以问一个关于连接的问题吗?我的意思是,据我所知,SELECT语句创建临时结果表,并在每个联接中向该结果表添加列。我说得对吗?