4

我需要帮助来理解这件事,下面的 2 个查询有什么区别,我只知道它们不会返回相同的结果。

查询一:

SELECT a.col1, b.c1
  FROM A a
  LEFT JOIN B b
    ON a.col1 = b.c1
 WHERE b.status = 'Y'

查询 2:

SELECT a.col1, b.c1
  FROM A a, B b
 WHERE a.col1 *= b.c1
   AND b.status = 'Y'
4

5 回答 5

6

第一个查询:

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' ;

这可能会给出不同的结果,因为它是(逻辑上)不同的查询。

这就是你永远不应该使用这种旧语法的原因之一。有时它是模棱两可的,例如当有多个条件或多个外部连接时。

于 2012-12-07T15:09:59.537 回答
5

我知道 Sybase 和 SQL Server 密切相关。*=已从 SQL Server 中删除,但即使早在 SQL Server 2000 中,它也无法正常工作,有时解释为左连接,有时解释为交叉连接。由于 Sybase 和 SQL Server 来自同一个基础产品,我怀疑这也是您的问题以及结果不同的原因。不要将隐式连接用于外连接,因为它不能可靠地给出正确答案。

这是 SQL Server 2000 联机丛书中讨论此问题的直接引述:

在 Microsoft® SQL Server™ 2000 的早期版本中,左外连接和右外连接条件是在使用 and运算符的WHERE子句中指定的。在某些情况下,这种语法会导致不明确的查询,可以用多种方式解释。子句中指定了符合 SQL-92 的外部连接,不会导致这种歧义。*==*FROM

于 2012-12-07T18:42:29.480 回答
4

抱歉有点晚了,但我找到了解决方案:在旧语法*=中,条件b.Status = 'Y'将在左连接 on 子句中,所以在第一个查询中必须得到相同的结果,我只是将b.Status = 'Y'“on”子句移到.

于 2012-12-07T18:17:28.190 回答
0

这些查询看起来相同。你说他们不返回相同的结果。你有一个例子吗?

新旧连接符号的不同之处在于,您是否将连接位置移到了哪里

Select
  a.col1, 
  b.c1
From
  A
    Left Join
  B 
    On a.col1 = b.c1 And b.Status = 'Y';

这是不同的,不能用旧的表示法这么容易地表示(至少不是在 Oracle 中,没有直接的 Sybase 经验)

示例(尽管 Oracle 使用(+)而不是*=

于 2012-12-07T14:57:40.453 回答
0

当涉及超过 2 个包含许多 where 子句的表时,我试图找到旧查询到新查询的转换,但在网上的任何地方都找不到它,因此在此处发布我的解决方案。如果您遵循以下技巧,结果将完全匹配:

在以下查询的情况下:

    select a.*
    from A a, B b, C c
    where a.server_id=0
    and a.name = 'John'
    and a.country_id*=b.value_cd
    and b.table_nm = 'Employee'
    and b.Attribute_nm ='A_nm'
    and a.state_id*= c.value_cd
    and c.table_nm = 'Company'

除了第一个表(即表 A)之外的所有 where 条件都可以进入连接中的 on 子句,但是第一个表的 Where 条件应保留在 Where 子句中,如下面的查询:

    select a.*
    from A a
    left join B b on a.country_id = b.value_cd 
       and b.table_nm = 'Employee' 
       and b.Attribute_nm ='A_nm'
    left join C c on a.state_id = c.value_cd 
       and c.table_nm = 'Company' 
    where a.server_id=0
       and a.name = 'John'
于 2019-05-16T17:08:57.763 回答