参考文章:Difference between WHERE and ON in SQL to JOIN data (dataschool.com)
在潜移默化的语法规范上,ON 应该用于定义连接条件,而 WHERE 应该用于过滤数据
如此区分将提高查询语句的可读性,且可以防止在使用 INNER JOIN 以外的 JOIN 类型时检索到不正确的数据
显式连接和隐式连接
SELECT *
FROM 表1
JOIN 表2
ON 表1.字段 = 表2.字段
SELECT *
FROM 表1
JOIN 表2
WHERE 表1.字段 = 表2.字段
SELECT *
FROM 表1, 表2
WHERE 表1.字段 = 表2.字段
以上三条语句的结果相同,区别在于:
前两者是显式连接,最后一条语句是隐式连接
显式连接使用 JOIN 子句,在 ON 子句中指定连接的类型和条件来明确告诉用户如何连接数据
隐式连接不指定连接类型,默认为内连接,使用 WHERE 子句来定义连接条件
可读性
显然,显式查询的可读性比隐式查询更强,如果按社区规范将连接条件定义在 ON 子句中,将过滤语句定义在 WHERE 子句中,将使查询语句的功能一目了然
隐式连接默认充当 INNER JOIN(内连接),如果想使用其他的连接方式,必须采用显式连接
在 WHERE 子句中同时定义连接条件将使得查询语句冗长且降低可读性
ON 子句也可以用于过滤数据,但使用它过滤数据同样会让查询语句冗长且降低可读性,更糟的是,在外连接中使用 ON 子句创建过滤条件可能会产生意外结果
性能优化
有时以不同的方式编写查询可以提高速度,但多数情况下使用 WHERE 和 ON 实现的连接在底层的查询计划是相同的,理论上没有任何性能区别
当然查询计划的创建方式可能因 SQL 语言和版本而异
疑点
有一个说法是ON 子句对每次笛卡儿积的中间结果进行过滤,而 WHERE 子句对最终结果进行过滤
该说法未查证真伪,但这似乎为采取社区的语法规范提供了理由:由该说法可得在外连接时,使用 ON 而不是 WHERE 来设置连接条件将提高效率
还有一说是内连接效率不如左外连接,但在该文章修改过程中已证伪打假:
mysql的内连接与外连接效率(验证)_虚无V旋涡的博客-CSDN博客_内连接和外连接效率
社区语法规范
社区语法规范不是强制性的,但按照社区语法规范来编写语句能大大提高代码可读性,你好,我也好
(当然如果你要恶心项目组写出第二天只有上帝能看懂的代码也可以反其道而行之)
-
使用 JOIN 子句来显式表达连接查询
-
在连接语句和条件过滤语句之间换行来保持良好的可读性
-
在 ON 子句中声明连接条件
-
在 WHERE 子句中声明过滤条件