INNER JOIN 与“FROM”中的多个表名 [重复]

Posted

技术标签:

【中文标题】INNER JOIN 与“FROM”中的多个表名 [重复]【英文标题】:INNER JOIN vs multiple table names in "FROM" [duplicate] 【发布时间】:2011-07-04 08:44:34 【问题描述】:

可能重复:INNER JOIN versus WHERE clause — any difference?

INNER JOIN 查询和隐式连接查询(在 FROM 关键字后列出多个表)有什么区别?例如:

给定以下两个表:

CREATE TABLE Statuses(
  id INT PRIMARY KEY,
  description VARCHAR(50)
);
INSERT INTO Statuses VALUES (1, 'status');

CREATE TABLE Documents(
  id INT PRIMARY KEY,
  statusId INT REFERENCES Statuses(id)
);
INSERT INTO Documents VALUES (9, 1);

这两个 SQL 查询有什么区别?根据我所做的测试,它们返回相同的结果。他们做同样的事情吗?是否存在它们会返回不同结果集的情况?

SELECT s.description FROM Documents d, Statuses s WHERE d.statusId = s.id AND d.id = 9;

SELECT s.description FROM Documents d INNER JOIN Statuses s ON d.statusId = s.id WHERE d.id = 9;

【问题讨论】:

没有区别。其次是更好的语法,它可以更清楚地了解连接条件,而无需查看其他地方,并且可以帮助避免无意的交叉连接。 【参考方案1】:

没有理由使用隐式连接(带有逗号的连接)。是的,对于内部连接,它将返回相同的结果。但是,它会受到无意的交叉连接的影响,尤其是在复杂的查询中,并且更难维护,因为左/右外连接语法(在 SQL Server 中已弃用,它现在无论如何都不能正常工作)因供应商而异。由于您不应该在同一个查询中混合使用隐式和显式连接(您可能会得到错误的结果),因此需要将某些内容更改为左连接意味着重写整个查询。

【讨论】:

“在 SQL Server 中甚至已弃用”——请引用。 在书籍中在线搜索已弃用的功能 [SQL Server] 我看到 Use of *= and =* 已被弃用 (msdn.microsoft.com/en-us/library/ms143729.aspx) 但这类似于 OUTER JOIN。你能告诉我我在寻找什么类似于INNER JOIN 的措辞吗?再次感谢。 ...我必须说我很难相信 SQL Server 团队会弃用核心 SQL-92 功能。 我没有说内连接只被外连接弃用了。【参考方案2】:

第一个对这两个表中的所有记录进行笛卡尔积,然后按 where 子句过滤。

第二个只连接满足您的 ON 子句要求的记录。

编辑:正如其他人所指出的,优化引擎将负责对笛卡尔积的尝试,并且或多或少会产生相同的查询。

【讨论】:

SQL 用英文是这么说的,但是 RDBMS 引擎没那么简单。优化引擎根本不会生成笛卡尔积。 @Dems 答案是有效的。这就是 SQL 语法所表明的。 RDBMS 的优化引擎对 SQL 语法的作用是另一个话题。不过,您关于引擎优化它的声明是有效的。我将添加注释。 同意,我只是想说,表达问题的方式并不总是与 RDBMS 采取的实际行动直接相关。它只对结果实施逻辑约束,而不是结果是如何得出的。【参考方案3】:

第二种方法的好处在于它有助于将连接条件(on ...)与过滤条件(where ...)分开。这有助于使查询的意图更具可读性。

连接条件通常更能描述数据库的结构和表之间的关系。例如,salary 表通过 EmployeeID 列与employee 表相关联,涉及这两个表的查询可能总是连接到该列。

过滤条件更能描述查询正在执行的特定任务。如果查询是 FindRichPeople,那么 where 子句可能是“wheresalary.Salary > 1000000”...这是描述手头的任务,而不是数据库结构。

请注意,SQL 编译器不会这样看...如果它决定交叉连接然后过滤结果会更快,它会交叉连接并过滤结果。它不关心 ON 子句中的内容和 WHERE 子句中的内容。但是,如果 on 子句匹配外键或连接到主键或索引列,则通常不会发生这种情况。就正确操作而言,它们是相同的;就编写可读、可维护的代码而言,第二种方式可能要好一些。

【讨论】:

【参考方案4】:

在您给出的示例中,查询是等效的;如果您使用的是 SQL Server,请运行查询并显示实际的执行计划以查看服务器在内部执行的操作。

【讨论】:

【参考方案5】:

有点像。可以帮到你。

Left join vs multiple tables in SQL (a) Left join vs multiple tables in SQL (b)

【讨论】:

【参考方案6】:

如果你用第一种方法,30 岁以下的人可能会对你嗤之以鼻,但只要你在做内连接,他们就会产生相同的结果,优化器也会产生相同的执行计划(至少据我所知)。

这当然假定第一个查询中的 where 子句是您在第二个查询中加入的方式。

顺便说一句,这可能会作为副本关闭。

【讨论】:

我未满 30 岁,所以我想这就是我一直使用 INNER JOIN 的原因:)。我认为它看起来更美观。【参考方案7】:

据我所知,没有区别的是第二个带有内部连接的新方法来编写此类语句,而第一个是旧方法。

【讨论】:

已经 19 岁了,这不是“新”方式。 好吧,我们称之为更新的方式;)

以上是关于INNER JOIN 与“FROM”中的多个表名 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

MySQL内连接(INNER JOIN)

mysql

26.MySQL中的内连接INNER JOIN

SQLServer中 join 跟inner join的区别是啥?

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

mysql的unionleft join right join inner join和视图学习