如果没有提供表别名,将采用什么表?

时间:2017-05-29 13:44:47

标签: sql sql-server

我正在分析一个SQL语句,并且有一些关于别名的内容对我来说并不是很清楚,所以我想问一下是否有人可以尝试解释它。所以,这就是声明的样子

SELECT 
    a.RecordID
    , a.Account
    , b.RecordID
    , c.SomeField as AlternativeFieldName
FROM TableA a
LEFT JOIN TableB b
    ON a.RecordID=b.RecordID
LEFT JOIN TableC c
    ON b.RecordID=c.RecordID
WHERE a.DayFrom >= YYYYMMDD and a.DayFrom < YYYYMMDD
    AND b.Field1 is null
    AND Field2 = 'SOME_VALUE'

正如您所看到的,语句中的所有三个表都提供了别名,并且总是在数据选择和连接中使用,但是在where子句中,上面的一个表中有一个字段没有提供别名。我不知道这是正确的,如果它是SQL作为源表的什么,或者它是否会抛出错误,如果它不是?

在这个page上,我尝试了类似的东西,它确实有效,尽管我预计会有一些错误。我认为如果连接多个表,SQL会强制您使用别名。这是声明

SELECT * 
FROM Customers c 
JOIN Orders o 
    ON c.CustomerID = o.CustomerID
WHERE OrderDate = '1996-07-04'
提前谢谢,欢呼!

3 个答案:

答案 0 :(得分:3)

如果SQL Server(或任何数据库)找到非限定列名,那么它会查看FROM子句中的哪些表/子查询或外部查询可能提供它。

如果列恰好位于FROM子句中的一个表/子查询中,则假定该列来自表/子查询。

如果列在FROM子句中的多个表/子查询中,则查询将返回错误。

如果FROM子句中的列不存在,也不存在任何外部查询,则查询将返回错误。

如果FROM子句中的列不存在,但外部查询中存在该列,则使用该引用。

这些规则的名称为&#34;范围&#34;。这是用于计算变量值的计算机语言中的常用术语。

答案 1 :(得分:2)

只要列名不明确,就不会为非限定列名引发错误。如果名称不明确,则必须使用表名或别名限定列名以避免错误。

请注意,当列名不合格时,范围的概念可能会成为问题。考虑这个结构:

WHERE b.Field3 IN(
   SELECT Field4
   FROM TableD
   )

如果Field4中存在TableD,则会返回所需的结果。但是如果{4}中不存在Field4但存在于其中一个外部表中,则当TableD值不为NULL且Field4中至少存在一行时,谓词对于所有外行都为true 1}}。

简而言之,最佳做法是在多表查询中限定列名。

答案 2 :(得分:0)

任何使用连接执行sql查询的RDBMS都会尝试从所有引用的表中查找列名。如果它只找到一个具有该名称的列,则只是通过模糊错误执行查询。别名将用于避免歧义。