使用逗号 (,) 左连接或从多个表中选择
我很好奇为什么我们需要使用 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
I'm curious as to why we need to use LEFT JOIN
since we can use commas to select multiple tables.
What are the differences between LEFT JOIN
and using commas to select multiple tables.
Which one is faster?
Here is my code:
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
...and:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,为了完全等效,应该编写第一个查询,
以便 mw.* 和 nvs.* 一起生成与第二个查询的单数 * 相同的集合。您编写的查询可以使用 INNER JOIN,因为它包含 nvs. Correct 上的过滤器。
一般形式
尝试
根据条件查找TableB记录。如果失败,则保留 TABLEA 中的结果,并将 TableB 中的所有列设置为 NULL。相比之下,还
尝试
根据条件查找 TableB 记录。 但是,当失败时,TableA 中的特定记录将从输出结果集中删除。CROSS JOIN 的 ANSI 标准生成 两个表之间的笛卡尔积。
该语法的目的是将 TABLEA 中的每一行连接到 TABLEB 中的每一行。因此,A 中的 4 行和 B 中的 3 行产生 12 行输出。当与 WHERE 子句中的条件配对时,它有时会产生与 INNER JOIN 相同的行为,因为它们表达相同的事物(A 和 B 之间的条件 => keep 或 not)。然而,当您使用 INNER JOIN 而不是逗号时,阅读意图会更清楚。
从性能角度来看,大多数 DBMS 处理 LEFT 连接的速度比处理 INNER JOIN 的速度更快。逗号表示法可能会导致数据库系统误解其意图并产生错误的查询计划 - 因此这是 SQL92 表示法的另一个优点。
为什么需要 LEFT JOIN? 如果上面对 LEFT JOIN 的解释仍然不够(在 A 中保留记录而在 B 中不匹配),那么考虑要实现相同的目的,您将需要一个复杂的 UNION在两个集合之间使用旧的逗号符号来达到相同的效果。 但如前所述,这不适用于您的示例,它实际上是隐藏在 LEFT JOIN 后面的 INNER JOIN。
注意:
LEFT OUTER JOIN
。First of all, to be completely equivalent, the first query should have been written
So that mw.* and nvs.* together produce the same set as the 2nd query's singular *. The query as you have written can use an INNER JOIN, since it includes a filter on nvs.correct.
The general form
attempts
to find TableB records based on the condition. If the fails, the results from TABLEA are kept, with all the columns from TableB set to NULL. In contrastalso
attempts
to find TableB records based on the condition. However, when fails, the particular record from TableA is removed from the output result set.The ANSI standard for CROSS JOIN produces a Cartesian product between the two tables.
The intention of the syntax is that EACH row in TABLEA is joined to EACH row in TABLEB. So 4 rows in A and 3 rows in B produces 12 rows of output. When paired with conditions in the WHERE clause, it sometimes produces the same behaviour of the INNER JOIN, since they express the same thing (condition between A and B => keep or not). However, it is a lot clearer when reading as to the intention when you use INNER JOIN instead of commas.
Performance-wise, most DBMS will process a LEFT join faster than an INNER JOIN. The comma notation can cause database systems to misinterpret the intention and produce a bad query plan - so another plus for SQL92 notation.
Why do we need LEFT JOIN? If the explanation of LEFT JOIN above is still not enough (keep records in A without matches in B), then consider that to achieve the same, you would need a complex UNION between two sets using the old comma-notation to achieve the same effect. But as previously stated, this doesn't apply to your example, which is really an INNER JOIN hiding behind a LEFT JOIN.
Notes:
LEFT OUTER JOIN
.将 JOIN 与 WHERE 分开使其易于阅读,因为连接逻辑不能与 WHERE 条件混淆。它通常也会更快,因为服务器不需要执行两个单独的查询并组合结果。
您给出的两个示例并不真正等效,因为您在第一个示例中包含了子查询。这是一个更好的例子:
Separating the JOIN from the WHERE makes it easy to read, as the join logic cannot be confused with the WHERE conditions. It will also generally be faster as the server will not need to conduct two separate queries and combine the results.
The two examples you've given are not really equivalent, as you have included a sub-query in the first example. This is a better example: