内连接中主表条件写在ON子句与WHERE子句的区别及原因?
这是个很好的问题!虽然对于INNER JOIN来说,把主表条件放在ON还是WHERE子句里,最终返回的结果集是完全一致的,但确实有几个合理的原因会让人选择把主表条件写在ON里:
逻辑分组更清晰,可读性更强
把和当前JOIN关联直接相关的所有条件(包括主表的筛选)都集中放在ON子句中,能让阅读代码的人一眼就明白这个JOIN的“关联规则+准入条件”是一个整体。比如你的示例代码:INNER JOIN dbo.JohnDataRecord AS jdr ON m.ibID = jdr.ibID AND m.MainID = @MainId AND jdr.SentDate IS NULL这里把主表
MainTable的MainID筛选和关联条件、子表的筛选放在一起,清晰传达了“我要关联的是MainTable中符合MainID = @MainId的行,以及JohnDataRecord中ibID匹配且SentDate为空的行”,和后续WHERE里针对全局结果的筛选(dr.lastRecordID IS NOT NULL)明确区分开,逻辑分层一目了然。便于后续修改JOIN类型,避免逻辑错误
如果哪天需要把INNER JOIN改成LEFT JOIN,把主表条件放在ON里就不会破坏原有逻辑。要是你把m.MainID = @MainId移到WHERE子句中,改成LEFT JOIN后,这个条件会直接过滤掉主表中不满足MainID = @MainId的行,相当于把LEFT JOIN又变回了INNER JOIN的效果——这是很多人改JOIN类型时容易踩的坑。而放在ON里的话,只需要修改JOIN关键字,逻辑就能保持正确。性能无差异,但可维护性更优
数据库的查询优化器对于INNER JOIN的这两种写法,几乎都会生成完全相同的执行计划,所以性能上没有区别。但从长期维护的角度看,把关联相关的条件都放在ON里,能减少后续开发者理解和修改代码时的混淆,降低出错概率。
总的来说,这种写法是符合SQL最佳实践的,核心目的是提升代码的可读性和可维护性,同时为未来的需求变更预留灵活性。
内容的提问来源于stack exchange,提问作者Mark Schultheiss

