“INNER JOIN”过滤条件在查询中的位置; `ON`或`WHERE`子句

时间:2014-08-12 19:35:23

标签: mysql

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'

OR:

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),则所有条件都在正确的位置。< / p>

然而,社区似乎有偏好第二种方式。

是否有人知道这种偏好是否有根据,可能是某些性能问题或某些可读性问题,我还没有发现?或者我可以继续成为反叛者吗?

2 个答案:

答案 0 :(得分:4)

它们都完全一样。唯一的决定因素是您在项目中使用的标准。你需要决定什么对你来说更具可读性并坚持下去。例如,格式化查询的方式不是我要做的。

我愿意

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子句中包含所有条件。这只是偏好

关于您对社区的看法,我认为大多数人会同意一致性是关键。确保您为其他开发人员记录您的方法并遵循该方法。如果表现受到影响,这将是一个不同的讨论,但事实并非如此。

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

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

答案 1 :(得分:2)

在内连接的情况下,即使存在不同的语义,它们在执行中也是等效的。查询优化器将检查和评估WHERE子句和FROM子句中的条件,并在构建查询计划时考虑所有这些因素,以便达到最有效的执行计划。所以你可以随心所欲地去。

同样正如你所说的值得注意的是,当用左/右连接替换内连接时,方程式会发生变化,并且你需要在'&#39; ON&#39;子句。