我很好奇为什么我们需要使用LEFT JOIN
,因为我们可以使用逗号来选择多个表。
LEFT JOIN
和使用逗号选择多个表之间有什么区别。
哪一个更快?
这是我的代码:
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT no as nonvs,
owner,
owner_no,
vocab_no,
correct
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0 )
AND mw.level = 1
...和
SELECT *
FROM vocab_stats vs,
mst_words mw
WHERE mw.no = vs.vocab_no
AND vs.correct > 0
AND mw.level = 1
AND vs.owner = 1111
答案 0 :(得分:4)
首先,要完全等效,应该编写第一个查询
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT *
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0 )
AND mw.level = 1
因此mw。*和nvs。*一起生成与第二个查询的单数*相同的集合。您编写的查询可以使用INNER JOIN,因为它包含nvs.correct上的过滤器。
一般表格
TABLEA LEFT JOIN TABLEB ON <CONDITION>
attempts
根据条件查找TableB记录。如果失败,则保留TABLEA的结果,并将TableB中的所有列设置为NULL。相比之下
TABLEA INNER JOIN TABLEB ON <CONDITION>
还 attempts
根据条件查找TableB记录。 但是,失败时,TableA中的特定记录将从输出结果集中删除。
CROSS JOIN的ANSI标准在两个表之间产生Cartesian product。
TABLEA CROSS JOIN TABLEB
-- # or in older syntax, simply using commas
TABLEA, TABLEB
语法的意图是TABLEA中的EACH行连接到TABLEB中的EACH行。因此A中的4行和B中的3行产生12行输出。当与WHERE子句中的条件配对时,它有时会产生INNER JOIN的相同行为,因为它们表达相同的事物(A和B之间的条件=&gt;保持与否)。但是,当您使用INNER JOIN而不是逗号时,在阅读意图时会更清楚。
在性能方面,大多数DBMS将比INNER JOIN更快地处理LEFT连接。逗号表示法可能会导致数据库系统误解意图并产生错误的查询计划 - 这是SQL92表示法的另一个优点。
为什么我们需要LEFT JOIN?如果上面的LEFT JOIN的解释仍然不够(将记录保存在B中没有匹配的B中),那么考虑到实现相同,你需要两个集合之间的复杂UNION使用旧的逗号表示法来实现相同的效果。 但如前所述,这不适用于您的示例,这实际上是隐藏在LEFT JOIN后面的INNER JOIN。
注意:
LEFT OUTER JOIN
。答案 1 :(得分:0)
将JOIN与WHERE分开使其易于阅读,因为连接逻辑不能与WHERE条件混淆。它通常也会更快,因为服务器不需要进行两个单独的查询并组合结果。
您给出的两个示例并不是真正等效的,因为您在第一个示例中包含了一个子查询。这是一个更好的例子:
SELECT vs.*, mw.*
FROM vocab_stats vs, mst_words mw
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no
WHERE vs.correct > 0
AND mw.level = 1
AND vs.owner = 1111