我在SQL zoo上通过the JOIN tutorial工作。
我们说我即将执行以下代码:
SELECT a.stadium, COUNT(g.matchid)
FROM game a
JOIN goal g
ON g.matchid = a.id
GROUP BY a.stadium
实际上,它产生的输出与下面的代码相同:
SELECT a.stadium, COUNT(g.matchid)
FROM goal g
JOIN game a
ON g.matchid = a.id
GROUP BY a.stadium
那么,什么时候你在FROM分配哪个表以及你在JOIN分配哪个表有什么关系呢?
答案 0 :(得分:1)
当你只加入2个表时,通常顺序无关紧要:MySQL以最佳顺序扫描表。
当您扫描超过2个表时,订单可能很重要:
SELECT ...
FROM a
JOIN b ON ...
JOIN c ON ...
此外,MySQL尝试以最快的方式扫描表(首先是大表)。但是如果连接速度很慢,MySQL可能会以非最佳顺序扫描它们。您可以使用EXPLAIN
验证这一点。在这种情况下,您可以通过添加STRAIGHT_JOIN
关键字来强制加入订单。
答案 1 :(得分:1)
当您使用INNER JOIN
时,就像您在这里一样,订单并不重要。这是因为您在一个公共索引上连接两个表,因此您使用它们的顺序取决于您。您应该选择最合乎逻辑的订单,并且最容易阅读。我的一个习惯是把我从头开始选择的表格。在你的情况下,你选择了来自游戏桌的体育场信息,所以我倾向于把它放在第一位。
但是,在其他联接中,例如LEFT OUTER JOIN
和RIGHT OUTER JOIN
,订单将很重要。这是因为这些连接将从一个表中选择所有行。例如,考虑我有一个Students
表和一个Projects
表。它们可以独立存在,有些学生可能有相关的项目,但不是全部都会。
如果我想在没有项目的情况下看到所有学生和项目信息,我需要LEFT JOIN
:
SELECT s.name, p.project
FROM student s
LEFT JOIN project p ON p.student_id = s.id;
请注意,LEFT JOIN
引用FROM
子句中的表格,这意味着所有学生都被选中。这也意味着p.project
对于某些行将为null。订单在这里很重要。
如果我使用RIGHT JOIN
采用相同的概念,它将从join子句中的表中选择所有行。所以,如果我将查询更改为:
SELECT s.name, p.project
FROM student s
RIGHT JOIN project p ON p.student_id = s.id;
这将返回项目表中的所有行,无论它是否与学生匹配。这意味着在某些行中,s.name
将为null。与第一个示例类似,因为我已将project
作为外部联接表,p.project
将永远不会为空(假设它不在原始表中)。在第一个示例中,s.name
永远不应为null。
在外连接的情况下,顺序很重要。值得庆幸的是,您可以通过LEFT
和RIGHT
联接直观地思考。左连接将返回该语句左侧的表中的所有行,而右连接将返回该语句右侧的所有行。以此为经验,但要小心。您可能希望开发一个与您自己一致的模式,正如我之前提到的那样,因此您可以在以后更容易理解这些查询。
答案 2 :(得分:0)
订单并不总是重要的,我通常只是以对阅读查询的人有意义的方式订购。
有时候订单很重要。使用LEFT JOIN
和RIGHT JOIN
进行试用。
答案 3 :(得分:0)
在这种情况下,您使用的是INNER JOIN
,如果您希望匹配公共ID或外键,则可能并不重要。
如果您执行OUTER JOIN
,则需要以正确的方式指定表格,因为并非所有类型的连接中的所有记录都通过相同的字段匹配。
答案 4 :(得分:0)
是的,当您再次使用其他加入LEFT JOIN
,RIGHT JOIN
时,这很重要
目前您正在使用返回所有表相关数据的NATURAL JOIN
,如果JOIN表行不匹配,则它将从结果中排除行
如果您使用 LEFT / RIGHT {OUTER} 加入,则结果会有所不同,请点击this link了解更多详情