内部联接或 WHERE 子句中的 AND 语句之间的区别

Posted

技术标签:

【中文标题】内部联接或 WHERE 子句中的 AND 语句之间的区别【英文标题】:Difference between the AND statement in an Inner Join or in a WHERE clause 【发布时间】:2012-03-21 23:18:52 【问题描述】:

大家好,我有一个关于 SQL 中的 AND 子句的具体问题。

以下两个 SQL 语句提供相同的输出:

SELECT * FROM Table1 t1 INNER JOIN Table2 t2 ON t1.id = t2.id AND t2.id = 0


SELECT * FROM Table1 t1 INNER JOIN Table2 t2 ON t1.id = t2.id WHERE t2.id = 0

请注意查询末尾的差异。在第一个中,我使用了 AND 子句(之前没有使用 WHERE 子句)。在第二个中,我使用 WHERE 来指定我的 id。

    第一个语法正确吗? 如果是,第一个在性能方面是否更好(不使用 WHERE 子句进行过滤)? 我应该期待不同的输出与不同的查询吗?

感谢您的帮助。

【问题讨论】:

你可以看一下数据库生成的查询计划,看看有没有不同。对于 mysql 数据库,您可以使用 EXPLAIN 语句执行此操作,对于其他数据库可能有类似的内容。 【参考方案1】:

是,不是,也不是。

具体来说:

    是的,语法是正确的。从概念上讲,第一个查询使用连接条件t1.id = t2.id AND t2.id = 0t1t2 之间创建一个内连接,而第二个查询在t1.id = t2.id 上创建一个内连接,然后使用条件t2.id = 0 过滤结果。

    但是,我所知道的任何 SQL 引擎都不会真正执行这样的查询。相反,在这两种情况下,引擎都会将它们都优化为t1.id = 0 AND t2.id = 0,然后进行两次单行查找。

    不,几乎任何合理的 SQL 引擎都应该将这两个查询视为实际上相同。

    不,见上文。

顺便说一下,同样的查询,下面的写法也是有效的:

SELECT * FROM Table1 t1 INNER JOIN Table2 t2 WHERE t1.id = t2.id AND t2.id = 0

SELECT * FROM Table1 t1, Table2 t2 WHERE t1.id = t2.id AND t2.id = 0

【讨论】:

不错的答案。使用 INNER JOIN,事情变得非常简单。使用 OUTER JOIN 和适当复杂的条件,过滤操作是在 JOIN 中还是在(主查询的)WHERE 子句中可能会有所不同。 谢谢主要​​答案。是的,在外连接的情况下,我注意到了这个乔纳森。感谢您的输入!编辑:是的第二种方式 Ilmary 但我宁愿坚持使用 ANSI 语法。 我认为 Ilmari Karonen 已经给出了很好的答案。使用 INNER JOIN ON 部分定义表之间的连接(如 t1.id = t2.id),并将 WHERE 部分用于业务规则,如 where t2.amount = 0。没有速度损失,只有为人类读者提供更清晰的代码。 还有SELECT * FROM Table1 t1, Table2 t2 WHERE t1.id = 0 AND t2.id = 0 @Ilmari Karonen:Table1 t1 INNER JOIN Table2 t2 WHERE ... 仅在 MySQL 中有效。如果你做了CROSS JOIN,是的,它是有效的。

以上是关于内部联接或 WHERE 子句中的 AND 语句之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2005 - 内部联接的顺序

如何使用 sql server exists 子句进行优化?

简述SELECT语句中的FROM、WHERE以及ORDER BY子句的作用。SQL Server

LINQ to SQL 中的内部联接的语法是啥?

如何在 mysqli 准备语句中使用多个内部连接和多个 WHERE 子句? [复制]

MySQL:内部联接与 Where [重复]