`INNER JOIN` 过滤条件在查询中的位置; `ON` 或 `WHERE` 子句 [关闭]

Posted

技术标签:

【中文标题】`INNER JOIN` 过滤条件在查询中的位置; `ON` 或 `WHERE` 子句 [关闭]【英文标题】:Position of `INNER JOIN` filtering conditions in a query; `ON` or `WHERE` clause [closed] 【发布时间】:2014-10-06 00:22:44 【问题描述】:

this question 上有一个与此相关的答案。但我觉得它值得自己提出一个问题。

This question,它被标记为与第一个重复但实际上并非如此,这是我想问的......正如它在位中所说的那样:

这个问题已经被问过并且已经有了答案。如果这些答案不能完全解决您的问题,请提出新问题

所以我要问一个新问题。

我可以写一个查询:

SELECT *
  FROM customer_order co
  JOIN customer c 
    ON c.id = co.customer_id
   AND c.type = 'special'
  JOIN order o
    ON o.id = co.order_id
   AND o.status = 'dispatched'

或者:

SELECT *
  FROM customer_order co
  JOIN customer c 
    ON c.id = co.customer_id
  JOIN order o
    ON o.id = co.order_id
 WHERE c.type = 'special'
   AND o.status = 'dispatched'

我绝对喜欢第一种方式,尤其是在更复杂的查询中,因为它将条件与它们所操作的表分组在一起,这使我更容易阅读和识别适当的复合索引。这也意味着如果我想换成LEFT JOIN(或者可能是RIGHT JOIN,我并没有真正使用RIGHT JOIN),所有的条件都在正确的地方。

不过,社区中似乎有些偏爱第二种方式。

有没有人知道这种偏好是否有根据,可能是由于某些性能问题或某些我尚未偶然发现的可读性问题?还是我可以继续快乐地做一个叛逆者?

【问题讨论】:

谢谢伊恩,是的,更多的方法!但是,this question 中几乎涵盖了该方法。 不错的链接,我实际上并不确定。看起来您问题中的两个链接都是相同的。我也对这个问题的答案很感兴趣。 @IanSellar 啊,已更正第二个链接!看起来我们有一个神秘的downvoter,我对无法解释的批评持批评态度。我希望得到一个体面的答案。 如何用大量数据填充您的示例表并查看两个查询的执行计划。我承认我是一个保守的人,并且将连接条件用于连接两个表的条​​件和 where 子句来限制结果。我认为这是按功能对条件进行分组。我没有使用隐式连接,因为它们很容易出错并且不会与外部连接真正混合。 因主要基于意见而关闭? OP 特别问:“有没有人知道这种偏好是否有根据,可能是在一些性能问题或一些我还没有偶然发现的可读性问题上?”换句话说,不是基于意见,而是要求使用其中一个或另一个的理由。 “没有区别,只是意见”可能是一个有效的答案,但这不是结束的理由。 【参考方案1】:

在内部连接的情况下,两者在执行上确实是等价的,即使有不同的语义。查询优化器将审查和评估 WHERE 子句和 FROM 子句中的条件,并在构建查询计划时考虑所有这些因素,以达到最有效的执行计划。所以你可以随心所欲。

正如您所说,值得注意的是,当内连接被左/右连接替换时,方程会发生变化,您需要在“ON”子句上使用过滤器。

【讨论】:

【参考方案2】:

两者完全相同。唯一的决定因素是您在项目中使用的标准。你需要决定什么对你来说更具可读性,然后去做。例如,您格式化查询的方式不是我会做的。

我愿意

SELECT 
  *
FROM 
  customer_order co

  INNER JOIN customer c ON 
    c.id = co.customer_id AND 
    c.type = 'special'

  INNER JOIN order o ON 
    o.id = co.order_id AND 
    o.status = 'dispatched'

我的和你的没有区别,只是我觉得我的可读性更强。根据经验,我通常为与基表相关的语句保留 where 子句。此外,内部连接中的第一列将与正在连接的表相关(例如 o.id 或 c.id)。这些都是我用来保持一致性的东西。另一个开发人员可能更喜欢在 where 子句中包含所有条件。这只是偏好

关于您对社区的看法,我想大多数人都会同意一致性是关键。确保您为其他开发人员记录了您的方法并继续使用。如果性能受到影响,这将是一个不同的讨论,但事实并非如此。

继续你正在做的事情,但要确保它是一致的!

另外,对于这样的问题,我认为代码审查论坛是一个更好的地方,人们不太可能对你的问题投反对票。

【讨论】:

以上是关于`INNER JOIN` 过滤条件在查询中的位置; `ON` 或 `WHERE` 子句 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Oracle中Inner join和Where的区别

26.MySQL中的内连接INNER JOIN

Oracle中Inner join和Where的区别

具有 INNER JOIN 条件的 JPA 命名查询失败

如何在 C# 中使用特定的 INNER JOIN 查询和条件制作 Crystal Report

SQL server 使用 内联结(INNER JOIN) 联结多个表 (以及过滤条件 WHERE, AND使用区别)