【发布时间】:2011-01-15 13:36:02
【问题描述】:
似乎要合并两个或多个表,我们可以使用 join 或 where。一个比另一个有什么优势?
【问题讨论】:
-
根据您的使用情况,它可能具有相同的结果,但使用 JOIN 您可以进行其他类型的关联。
-
这能回答你的问题吗? INNER JOIN ON vs WHERE clause
似乎要合并两个或多个表,我们可以使用 join 或 where。一个比另一个有什么优势?
【问题讨论】:
显式连接传达意图,让 where 子句进行过滤。它更干净,它是标准的,你可以做一些事情,比如左外或右外,这只是在哪里更难做到。
【讨论】:
大多数人倾向于发现 JOIN 语法更清楚地表明了什么是与什么相连接的。此外,它还具有成为标准的好处。
就我个人而言,我是在 WHERE 上“长大”的,但是我使用 JOIN 语法的次数越多,我就越开始明白它是如何变得更加清晰的。
【讨论】:
您不能使用 WHERE 来组合两个表。你可以做的是写:
SELECT * FROM A, B
WHERE ...
这里的逗号相当于写:
SELECT *
FROM A
CROSS JOIN B
WHERE ...
你会写吗?不——因为这根本不是你的意思。你不想要一个交叉连接,你想要一个内部连接。但是当你写逗号时,你说的是 CROSS JOIN,这很令人困惑。
【讨论】:
任何涉及多个表的查询都需要某种形式的关联来将表“A”的结果链接到表“B”。执行此操作的传统 (ANSI-89) 方法是:
在WHERE子句中写表之间的关联
SELECT *
FROM TABLE_A a,
TABLE_B b
WHERE a.id = b.id
这是使用 ANSI-92 JOIN 语法重写的查询:
SELECT *
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
在受支持的情况下(Oracle 9i+、PostgreSQL 7.2+、MySQL 3.23+、SQL Server 2000+),使用任何一种语法都没有性能优势。优化器将它们视为相同的查询。但是更复杂的查询可以从使用 ANSI-92 语法中受益:
使用 ANSI-92 JOIN 语法而不是 ANSI-89 的原因有很多:
ANSI-92 JOIN 语法是模式,而不是反模式:
缺乏熟悉和/或舒适,我认为继续使用 ANSI-89 WHERE 子句而不是 ANSI-92 JOIN 语法没有任何好处。有些人可能会抱怨 ANSI-92 语法更冗长,但这正是它明确的原因。越明确,就越容易理解和维护。
【讨论】:
这些是使用 where 语法(也称为隐式连接)的问题:
首先,很容易意外交叉连接,因为连接条件不在表名旁边。如果将 6 个表连接在一起,则很容易在 where 子句中遗漏一个。通过使用 distinct 关键字,您会经常看到此问题已得到解决。这对数据库来说是巨大的性能损失。您不能使用显式连接语法意外交叉连接,因为它会导致语法检查失败。
在某些数据库的旧语法中,右连接和左连接存在问题(在 SQl 服务器中,您不能保证获得正确的结果)。此外,它们在我知道的 SQL Server 中已被弃用。
如果您打算使用交叉连接,旧语法中并不清楚。使用当前的ANSII标准很清楚。
对于维护者来说,使用隐式语法准确地查看哪些字段是连接的一部分,甚至哪些表以什么顺序连接在一起要困难得多。这意味着修改查询可能需要更多时间。我认识的人很少,一旦他们花时间对显式连接语法感到满意,就会回到旧的方式。
我还注意到,一些使用这些隐式连接的人实际上并不了解连接的工作原理,因此在他们的查询中得到了不正确的结果。
老实说,您会使用 18 年前被更好方法取代的任何其他类型的代码吗?
【讨论】:
其实你经常需要“WHERE”和“JOIN”。
“JOIN”用于从两个表中检索数据 - 基于公共列的值。如果您想进一步过滤此结果,请使用 WHERE 子句。
例如,“LEFT JOIN”检索左表中的所有行,以及右表中的匹配行。但这不会过滤任何特定值或不属于 JOIN 的其他列的记录。因此,如果您想进一步过滤此结果,请在 WHERE 子句中指定额外的过滤器。
【讨论】: