为什么使用JOIN子句而不是WHERE条件?

Jay*_*Jay 12 sql oracle

我针对Oracle数据库开发.当我需要手动编写(不使用像hibernate这样的ORM)时,我使用WHERE条件而不是JOIN.

例如(这只是用来说明风格的简单化):

Select *
from customers c, invoices i, shipment_info si
where c.customer_id = i.customer_id
    and i.amount > 999.99 
    and i.invoice_id = si.invoice_id(+)  -- added to show a replacement for a join
order by i.amount, c.name
Run Code Online (Sandbox Code Playgroud)

我从OLD oracle DBA那里学到了这种风格.我从那时起就知道这不是标准的SQL语法.除了非标准和更少的数据库便携性,使用这种格式还有其他任何影响吗?

Han*_*Gay 16

我不喜欢这种风格,因为它更难以确定哪些WHERE条款用于模拟JOINs,哪些条款用于实际过滤器,我不喜欢使代码更难以确定程序员的原始意图.

  • 为"我不喜欢能够确定程序员原始意图的不必要的代码"的+1 (3认同)
  • +1恕我直言这就是我们应该将JOIN用于FROM子句的原因.当连接与过滤条件分离时,它更清晰. (2认同)

Ada*_*ter 10

我遇到这种格式的最大问题是忘记一些连接WHERE条款的倾向,从而导致产生笛卡尔积.在向查询添加新表时,这种情况(对我来说至少是这种情况)很常见.例如,假设一个ADDRESSES表被抛入混合中,你的思想有点健忘:

SELECT *
  FROM customers c, invoices i, addresses a
 WHERE c.customer_id = i.customer_id
   AND i.amount > 999.99
 ORDER BY i.amount, c.name
Run Code Online (Sandbox Code Playgroud)

繁荣!笛卡尔积!:)

  • 周杰伦,遗憾的是没有大多数人不会看到这个问题,他们只是添加一个明显的,并继续他们的快乐方式. (5认同)
  • 这是真的,但是像所有(大多数)语法错误一样,当你尝试运行然后修复它时,你不会看到问题吗?这是我在这件事上的经验. (2认同)

Cha*_*ana 7

在某些情况下,旧式连接是错误的(外连接是罪魁祸首).虽然它们在使用内部联接时或多或少相等,但它们可能会在外部联接时生成不正确的结果,尤其是在外侧的列可以为null时.这是因为在使用旧语法时,在构造整个结果集之前不会对连接条件进行逻辑评估,因此根本无法在连接外部的列上表示条件,该列将在列可以过滤记录时为null,因为没有匹配的记录.

举个例子:

选择所有的客户,以及他们在本月8月,在发票已处理所有发票销售窗口小部件的总和(Invoice.ProcessDate是空)

使用新的ANSI-92 Join语法

 Select c.name, Sum(d.Amount)
 From customer c
    Left Join Invoice I 
        On i.custId = c.custId
            And i.SalesDate Between '8/1/2009' 
                      and '8/31/2009 23:59:59'
            And i.ProcessDate Is Not Null
    Left Join InvoiceDetails d 
        On d.InvoiceId = i.InvoiceId
            And d.Product = 'widget'
 Group By c.Name
Run Code Online (Sandbox Code Playgroud)

尝试使用旧语法执行此操作...因为在使用旧样式语法时,在重新添加"外部"行之前评估/应用where子句中的所有条件,所有未处理的发票行将被添加回到最终的结果集.所以这是不可能用旧的语法 - 任何试图筛选出与空加工日期的发票将消除客户...唯一的选择是使用相关子查询.

  • Oracle和SQL Server都有表达外连接的语法,Oracle使用'"+ ="'或'"= +"'而SQL Server曾使用'"*="'或'"=*"'来表示左边,和右外连接,分别...... (2认同)

Eri*_*ler 6

有些人会说这种风格的可读性较差,但这是习惯问题.从性能的角度来看,这没关系,因为查询优化器会处理这个问题.

  • 除了对于certian外连接查询,旧语法cab很容易给出不正确的结果,因此应该避免. (4认同)
  • 我发现它恰恰相反.将查询拆分为列,表,联接和其他限制因素时,它更具可读性.我发现(+)语法比ANSI更容易使用.个人喜好我想. (3认同)