加入FROM子句和WHERE子句有什么区别?

时间:2013-11-25 07:44:56

标签: sql oracle join inner-join outer-join

我们有一个Oracle 10g,我们的大多数应用程序都在运行Oracle Forms 6i。我发现在views / packages / procedures / functions中编写的所有查询都是WHERE子句级别的JOINING表。实施例

SELECT * FROM
  TABLE_A A,
  TABLE_B B,
  TABLE_C C,
  TABLE_D D
WHERE 
    A.ID=B.ID(+)
AND B.NO=C.NO(+)
AND C.STATUS=D.ID
AND C.STATUS NOT LIKE 'PENDING%'

此查询仅适用于ORACLE,因为它具有(+)连接限定符,这在其他SQL平台中是不可接受的。以上查询等同于:

SELECT * FROM
  TABLE_A A LEFT JOIN TABLE_B B ON A.ID=B.ID
  LEFT JOIN TABLE_C C ON B.NO=C.NO
  JOIN TABLE_D D ON C.STATUS=D.ID
WHERE
      C.STATUS NOT LIKE 'PENDING%'

我看到的非查询是在FROM子句中使用join进行编写的。

我的问题可以分为三个部分:

问:假设我有相同的Oracle环境,哪个查询在性能,缓存,CPU负载等方面更好。第一个(在WHERE加入)或第二个(在FROM加入)

问:是否有其他SQL实现接受除oracle之外的(+)连接限定符?如果是的话,哪个?

问:也许在WHERE子句中编写连接会使查询更具可读性但会影响LEFT / RIGHT连接的能力,这就是(+)的原因。我在哪里可以阅读更多关于这个(+)的起源以及为什么它是专门为Oracle发明的?

4 个答案:

答案 0 :(得分:9)

Q1。没有不同。您可以使用性能分析进行检查并比较执行计划。

Q2。据我所知,只有oracle支持它。但不建议在最新版本的Oracle RDBMS中使用:

  

Oracle建议您使用FROM子句OUTER JOIN语法   而不是Oracle join运算符。使用的外部联接查询   Oracle连接运算符(+)遵循以下规则和   限制,不适用于FROM子句OUTER JOIN语法:

Q3。在SQL ANSI中指定外连接之前的Oracle“发明”(+)。

答案 1 :(得分:4)

应该没有性能差异。假设您使用的是最新版本的Oracle,Oracle将隐式地将SQL 99语法转换为等效的Oracle特定语法。当然,所有软件都存在错误,因此有可能因为某些错误而导致其中一个或另一个执行不同的错误。 Oracle的版本越新,您就越不可能看到差异。

创建了(+)运算符(以及其他数据库中的各种其他外连接运算符),因为SQL标准在SQL 99标准之前没有表达外连接的标准方法。在此之前,每个供应商都创建了自己的扩展。 Oracle花了几年时间来支持新语法。在SQL 99支持的初始版本中更常见的错误(不常见但比现在更常见)之间的事实,产品需要继续支持不支持新语法的旧数据库版本,以及人们通常满足于旧的语法,今天仍然有大量的代码使用旧的Oracle语法。

答案 2 :(得分:0)

<强> A1:

据我所知,它们的语法方面不同,而不是性能。因此,加入'where'子句和加入'from'子句之间没有区别。

<强> A2:

为了更好地回答这个问题,“加入FROM”条款是所有平台的标准。所以忘掉(+)符号

<强> A3 我有时在Oracle工作过。人们使用(+)符号进行左/右连接,因为它易于编写。一些ppl使用join(FROM)子句,因为它更易读和易懂。

希望这些观点对你有所帮助。如果有任何问题,请告诉我。

答案 3 :(得分:0)

Oracle语法和ANSI语法之间的一个区别是: 在Oracle语法中,您无法进行FULL OUTER JOIN,您必须使用ANSI语法。

Oracle在Oracle 9i中引入了ANSI语法 - 包括一些错误。与此同时,自Oracle 11或12以来它运行良好,但您可能会发现Oracle 9/10中存在一些障碍。

ANSI Join语法的另一个优点是你不能忘记任何连接条件。

“SELECT * FROM TABLE_A,TABLE_B”隐式执行交叉连接。 “SELECT * FROM TABLE_A JOIN TABLE_B”引发错误,您被迫提供连接条件。如果你想要交叉连接,你必须指定它,即“SELECT * FROM TABLE_A CROSS JOIN TABLE_B”