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;
答案 0 :(得分:12)
如果你是第一种方式,那么30岁以下的人可能会对你轻笑,但只要你进行内部联接,他们就会产生相同的结果,优化器会生成相同的执行计划(至少就我所知道的而言。
这当然假定第一个查询中的where子句是你在第二个查询中加入的方式。
这可能会以副本的形式关闭,顺便说一句。
答案 1 :(得分:7)
没有理由使用隐式连接(带逗号的连接)。对于内部联接,它将返回相同的结果。但是,它会受到无意的交叉连接,尤其是在复杂查询中,并且维护起来比较困难,因为左/右外连接语法(在SQL Server中已弃用,现在无法正常工作)因供应商而异。由于您不应在同一查询中混合使用隐式和显式连接(您可能会得到错误的结果),因此需要将某些内容更改为左连接意味着重写整个查询。
答案 2 :(得分:5)
第二种方法的好处在于它有助于将连接条件(on ...)与过滤条件(其中......)分开。这有助于使查询的意图更具可读性。
连接条件通常更能描述数据库的结构和表之间的关系。例如,工资表与EmployeeID列的employee表相关,涉及这两个表的查询可能总是在该列上连接。
过滤条件更能描述查询正在执行的特定任务。如果查询是FindRichPeople,则where子句可能是“where salaries.Salary> 1000000”......那就是描述手头的任务,而不是数据库结构。
请注意,SQL编译器没有这样看...如果它决定交叉连接然后过滤结果会更快,它将交叉连接并过滤结果。它不关心ON子句中的内容和WHERE子句中的内容。但是,如果on子句匹配外键或连接到主键或索引列,通常不会发生这种情况。就操作正确而言,它们是相同的;至于编写可读,可维护的代码,第二种方式可能会好一点。
答案 3 :(得分:3)
据我所知,第二个内部连接是编写此类语句的新方法,第一个是旧方法。
答案 4 :(得分:3)
第一个在这两个表中的所有记录上都有一个笛卡尔积,然后按where子句过滤。
第二个只加入符合ON条款要求的记录。
编辑:正如其他人所指出的那样,优化引擎会处理笛卡尔积的尝试,并会或多或少地产生相同的查询。
答案 5 :(得分:0)
答案 6 :(得分:0)
在您给出的示例中,查询是等效的;如果您正在使用SQL Server,请运行查询并显示实际的执行计划,以查看服务器在内部执行的操作。