MS SQL 中的 SQL JOIN 语法

Jac*_*all 4 sql-server-2008 join

我在 MSSQL 课上教过,这是如何连接两个表

select * from FirstTable A
JOIN SecondTable B
on A.ID= B.ID
Run Code Online (Sandbox Code Playgroud)

现在在我的职业生涯中,我遇到过这样的 JOIN 查询

select * from FirstTable A, SecondTable B
where A.ID=B.ID
Run Code Online (Sandbox Code Playgroud)

我知道第二种选择曾经是常态,但现在可能已经放弃了。

我发现在我加入 6+ 个表 + 有多个子查询的复杂查询中,第二种形式更容易理解,而且简短漂亮。

问题

  • 我应该使用哪一种?
  • 一个比另一个有优势吗?

Rol*_*DBA 5

第二种类型的查询属于所谓的 SQL 反模式(查看 Bill Karwin 写的好书)。第二个查询几乎类似于笛卡尔 JOIN,它的 WHERE 子句必须即时计算。

第一个更干净,可以更好地管理执行顺序。

你可以比较两种方式

  • 为每个获取 EXPLAIN 计划并查看执行时间是否相同
  • 创建第三种类型来重构查询并获取其 EXPLAIN 计划和运行时间
  • 查看是否对三种查询样式的所有索引都进行了相同的评估

您最好使用 JOIN 语法,因为您可以使用 LEFT JOIN 和 RIGHT JOIN 生成结果集,这些结果集可能与 INNER JOIN 大不相同(可能比 INNER JOIN 更可取)。


Aar*_*ron 5

这个 SO 帖子很好地解释了 ANSI SQL 抱怨的差异。

虽然两个查询都会产生相同的结果,但我发现明确声明您的 JOIN 总是一个好主意。它更容易理解,尤其是在 WHERE 子句中包含非 JOIN 相关评估的查询中。

明确说明您的 JOIN 还可以避免您无意中生成笛卡尔积(如 RolandoMySQLSBA 所暗示的)。在上面的第二个查询中,如果您(无论出于何种原因)忘记包含 WHERE 子句,您的查询将在没有 JOIN 条件的情况下运行,并返回 FirstTable 中每一行与 SecondTable 中每一行匹配的结果集。除了不返回您想要的内容之外,如果您在大型表(具有数十万甚至数百万行)上犯了这样的错误,您可能会在数据库尝试执行该查询时导致一些性能问题。