如果我想用简单的连接编写查询,我可以这样做:
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标准(我猜这里 - 我不知道它是否符合要求)并鼓励良好的编码约定?
对于您的具体示例,我无法想到它会产生什么影响的任何情况.但是对于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)
省略表别名确实会产生不明确的列引用.只要你做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)