不明确的列名 - 是吗?

Pau*_*gle 4 sql t-sql

如果我想用简单的连接编写查询,我可以这样做:

select * from customer c
join order o
on c.customerid = o.customerid
where c.customerid = 100
Run Code Online (Sandbox Code Playgroud)

这一切都很好.在这个查询中,是否有必要指定表别名 - 即.c.customerid?为什么我不能写这个:

select * from customer c
join order o
on c.customerid = o.customerid
where customerid = 100
Run Code Online (Sandbox Code Playgroud)

我收到了错误Ambiguous column name 'customerid'.在这种情况下,WHERE子句中只有一列,并且它是我正在加入的列,这实际上是"模棱两可"吗?或者只是遵守ansi标准(我猜这里 - 我不知道它是否符合要求)并鼓励良好的编码约定?

Mar*_*ith 6

对于您的具体示例,我无法想到它会产生什么影响的任何情况.但是对于INNER JOIN字符串列,它可以执行如下操作.

DECLARE @customer TABLE
(customerid CHAR(3) COLLATE Latin1_General_CI_AS)

INSERT INTO @customer VALUES('FOO');

DECLARE @order TABLE
(customerid CHAR(3) COLLATE Latin1_General_CS_AS)

INSERT INTO @order VALUES('FOO');


SELECT * 
FROM @customer c
JOIN @order o
ON c.customerid = o.customerid COLLATE Latin1_General_CS_AS
WHERE c.customerid = 'Foo' /*Returns 1 row*/

SELECT * 
FROM @customer c
JOIN @order o
ON c.customerid = o.customerid COLLATE Latin1_General_CS_AS
WHERE o.customerid = 'Foo' /*Returns 0 rows*/
Run Code Online (Sandbox Code Playgroud)


Luk*_*der 5

省略表别名确实会产生不明确的列引用.只要你做join一个left join,你就会立即明白为什么:

select * from customer c
left join order o
on c.customerid = o.customerid
where customerid = 100 -- here, the semantics are quite different
Run Code Online (Sandbox Code Playgroud)

另一个原因:一列可以是类型INTEGER,另一列是类型SMALLINT.哪一个用于过滤器?(这可能会对执行计划产生影响).马丁史密斯给出了一个更好的例子

所以一般来说,通过使SQL更"宽容",同时引入新的错误来源,你不会获得太多收益.您可以使用某些数据库(而不是SQL Server)执行的操作是:

select * from customer c
join order o
using (customerid)
where customerid = 100
Run Code Online (Sandbox Code Playgroud)

或者这个(如果customerid是唯一的常用列名)

select * from customer c
natural join order o
where customerid = 100
Run Code Online (Sandbox Code Playgroud)