ANSI 和非 ANSI 连接有啥区别,您推荐哪一种? [复制]

Posted

技术标签:

【中文标题】ANSI 和非 ANSI 连接有啥区别,您推荐哪一种? [复制]【英文标题】:What is difference between ANSI and non-ANSI joins, and which do you recommend? [duplicate]ANSI 和非 ANSI 连接有什么区别,您推荐哪一种? [复制] 【发布时间】:2013-11-11 11:17:40 【问题描述】:

我访问了许多网站来找到关于哪个更好的答案,ANSI 或非 ANSI 语法。这两个查询有什么区别?

select a.name,a.empno,b.loc
from tab a, tab b
where a.deptno=b.deptno(+);

和:

select a.name,a.empno,b.loc
from tab a 
left outer join tab b on a.deptno=b.deptno;

这两种情况的结果是相同的。第二个查询也更长。哪个更好?

假设如果我们在上面的查询中添加了另一个表 Salgrade 基于我们需要加入它们的条件? .. 任何人都可以假设一张桌子并给我解释

【问题讨论】:

Oracle recommends to use ANSI joins: "Oracle 建议您使用 FROM 子句 OUTER JOIN 语法而不是 Oracle 连接运算符" 如果您有兴趣/计划将当前数据库迁移到 Azure,非 ANSI 样式即将发生重大变化(意味着最新版本的数据库不支持)。在迁移到 Azure 云之前,您必须将所有查询转换为 ANSI 标准。您可以通过搜索数据迁移助手(DMA)查看更多详细信息。 【参考方案1】:

这两种语法通常都可以正常工作,但如果您尝试添加 where 条件,您会发现使用第二种语法更容易理解哪个是连接条件,哪个是 where 子句。

1)

  SELECT a.name,
         a.empno,
         b.loc 
    FROM tab a,
         tab b 
   WHERE a.deptno = b.deptno(+)
     AND a.empno = 190;

2)

         SELECT a.name,
                a.empno,
                b.loc 
           FROM tab a,
LEFT OUTER JOIN tab b 
             ON a.deptno = b.deptno
          WHERE a.empno = 190;

此外,识别外连接要容易得多,而且不要忘记包含 (+)。总的来说,您可以说这只是一个品味问题,但事实是第二种语法更具可读性且不易出错。

【讨论】:

+1 我几乎只使用 Ansi join 语法,因为它更易读(恕我直言)。 你好 mucio,假设我们在上面的查询中添加了另一个表“Salgrade”,基于什么条件我们需要加入它们?你能用一个例子来解释一下如何加入 3 个或更多表吗.. 你的解释很好.. 那就是我特别问你 在这种情况下,在ON 条件之后,您将添加下一个连接及其条件。我这里准备了一个小demo来玩:sqlfiddle.com/#!4/7a147/10 非ANSI符号只能表达有限的条件。【参考方案2】:

第一种是传统的 Oracle 特定的连接编写方式,第二种是 ANSI SQL-92+ 标准,是首选。

【讨论】:

【参考方案3】:

广泛讨论了很多次,including one by me。

使用显式连接而不是隐式连接(无论它们是否是外连接)是因为使用隐式连接更容易意外创建笛卡尔积。

使用显式 JOIN,您不能“意外”创建一个。涉及的表越多,您错过一个连接条件的风险就越高。

与 ANSI 连接相比,基本上 (+) 受到严格限制。此外,它仅在 Oracle 中可用,而所有主要 DBMS 都支持 ANSI 连接语法

迁移到 ANSI 语法后,SQL 不会开始更好地执行 - 它只是语法不同。

Oracle 强烈建议您使用前面示例中显示的更灵活的 FROM 子句连接语法。过去,ANSI 语法存在一些错误,但如果您使用最新的 11.2 或 12.1,应该已经修复了。

使用 JOIN 运算符可确保您的 SQL 代码符合 ANSI,从而可以更轻松地将前端应用程序移植到其他数据库平台。

连接条件对每个表的选择性非常低,而对理论叉积中的元组选择性很高。 where 语句中的条件通常具有更高的选择性。

Oracle 在内部将 ANSI 语法转换为 (+) 语法,您可以在执行计划的谓词信息部分看到这种情况。

如果你使用的是 11.2,我建议加入 ANSI。如果你使用 12C,在 OUTER JOINS 上会发现一些新的 bug。

我还记得 Oracle 在 11.2 之前使用 ANSI 语法时的一些错误,这些错误在 11.2 中得到了修复。

在我看来,我不是 ANSI 语法的忠实拥护者,尽管 Oracle 确实符合 ANSI 的标准it is not totally bug free.

【讨论】:

【参考方案4】:

请阅读此article 关于连接的信息。 如果您在 B 表中而不在 A 表中有数据,则您的示例结果不一样

【讨论】:

以上是关于ANSI 和非 ANSI 连接有啥区别,您推荐哪一种? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Windows 记事本的 ANSI,Unicode,UTF-8 这三种编码模式有啥区别

旧式外连接 (+) 不能与 ANSI 连接一起使用,Oracle 数据库错误代码 ORA-25156

如何读取具有 ANSI 编码和非英文字母的文本文件?

ANSI C编程啥意思,跟我们现在学的c/c++有啥不同?

UNICODE与ANSI的区别

UNICODE与ANSI的区别