我需要帮助才能理解这个问题,下面两个查询之间有什么区别,我知道它们不会返回相同的结果。
SELECT a.col1, b.c1
FROM A a
LEFT JOIN B b
ON a.col1 = b.c1
WHERE b.status = 'Y'
和
SELECT a.col1, b.c1
FROM A a, B b
WHERE a.col1 *= b.c1
AND b.status = 'Y'
第一个查询:
SELECT
a.col1, b.c1
FROM
a LEFT JOIN b ON a.col1 = b.c1
WHERE
b.status = 'Y' ;
等同于内连接,因为b.status
部分使用了WHERE
列(来自左外连接的右侧):
SELECT
a.col1, b.c1
FROM
a INNER JOIN b ON a.col1 = b.c1
WHERE
b.status = 'Y' ;
第二个查询(可能)执行为:
SELECT
a.col1, b.c1
FROM
a LEFT JOIN b ON a.col1 = b.c1
AND b.status = 'Y' ;
这可能会给出不同的结果,因为它是(逻辑上)不同的查询。
这是你永远不应该使用这种旧语法的原因之一。有时它很模糊,例如当有多个条件或多个外连接时。
我知道Sybase和SQL Server密切相关。 *=
已从SQL Server中删除,但即使早在SQL Server 2000中,它也无法正常工作,有时会将其解释为左连接,有时也会解释为交叉连接。由于Sybase和SQL Server来自相同的基础产品,我怀疑这也是您的问题以及结果不同的原因。不要对外连接使用隐式连接,因为它不能可靠地给出正确的答案。
以下是针对SQL Server 2000的联机丛书的直接引用,其中讨论了此问题:
在早期版本的Microsoft®SQLServer™2000中,使用
WHERE
和*=
运算符在=*
子句中指定了左外连接条件和右外连接条件。在某些情况下,此语法会导致可能以多种方式解释的模糊查询。符合SQL-92的外连接在FROM
子句中指定,不会导致这种歧义。
很抱歉有点晚了,但我找到了解决方案:在旧语法*=
中,条件b.Status = 'Y'
将在左连接on子句中,所以在第一个查询中我必须将b.Status = 'Y'
移动到“关于“条款”。
这些查询看起来一样。你说他们没有返回相同的结果。你有一个例子吗?
旧的和新的连接符号确实不同的地方是你移动了连接的位置
Select
a.col1,
b.c1
From
A
Left Join
B
On a.col1 = b.c1 And b.Status = 'Y';
这是不同的,并且不能在旧的表示法中如此容易地表示(至少在Oracle中没有,没有Sybase的直接经验)
Example(尽管Oracle使用(+)
而不是*=
)