[英]How to make two joins between two tables in MySQL such that they are interlinked to each other?
I have two tables in a company database named employee
and branch
with a single foreign key each.我在名为
employee
和branch
的公司数据库中有两个表,每个表都有一个外键。 The employee
table looks like this: employee
表如下所示:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| emp_id | int | NO | PRI | NULL | auto_increment |
| first_name | varchar(30) | YES | | NULL | |
| last_name | varchar(30) | YES | | NULL | |
| birth_date | date | YES | | NULL | |
| sex | varchar(1) | YES | | NULL | |
| salary | int | YES | | NULL | |
| super_id | int | YES | MUL | NULL | |
| branch_id | int | YES | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
And the branch table looks like this:分支表如下所示:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| branch_id | int | NO | PRI | NULL | |
| branch_name | varchar(30) | YES | | NULL | |
| mgr_id | int | YES | MUL | NULL | |
| mgr_start_date | date | YES | | NULL | |
+----------------+-------------+------+-----+---------+-------+
In the employee table, the branch_id
foreign key references the branch_id
of the branch
table.在employee表中,
branch_id
外键引用了branch
表的branch_id
。 In the branch table, the manager_id
foreign key references the employee_id
of the employee
table.在分支表中,
manager_id
外键引用employee_id
中的employee
表。
I would form two joins between these two tables in circular fashion (saying informally) such that employee.branch_id
forms a join with branch.branch_id
, and such that branch.manager_id
forms a join with employee.employee_id
.我会以循环方式(非正式地说)在这两个表之间形成两个连接,这样
employee.branch_id
与branch.branch_id
形成连接,并且branch.manager_id
与employee.employee_id
形成连接。
So what I want the query with these two joins to return is:所以我希望这两个连接的查询返回的是:
employee.first_name AS employee_name, employee.branch_id, branch.branch_name, branch.manager_id, employee.employee_id AS manager_name
I couldn't think of a possible solution to this issue as the LEFT table in each of the joins is different and I don't know how to define multiple LEFT tables for each join in a single SQL query.我想不出这个问题的可能解决方案,因为每个连接中的 LEFT 表是不同的,而且我不知道如何在单个 SQL 查询中为每个连接定义多个 LEFT 表。
DBMS: MySQL v8.0.26数据库管理系统:MySQL v8.0.26
PS: My question is different from this question as in the aforementioned question, the LEFT table for both of the joins is the same and in my case, it is not. PS:我的问题与上述问题中的这个问题不同,两个连接的 LEFT 表是相同的,而在我的情况下,它不是。
Two joins can be formed between two columns by using Table aliases.通过使用表别名,可以在两列之间形成两个连接。 As the question specifies, that one join is to be formed between the
employee
and the branch
table, and another join needs to be formed between the branch
and the employee
table.如题所述,在
employee
和branch
表之间要形成一个join,在branch
和employee
表之间需要形成另一个join。 The little bit tricky part of these types of joins is the relation specified after the ON
keyword that joins the two tables.这些类型的连接有点棘手的部分是在连接两个表的
ON
关键字之后指定的关系。
As @philipxy writes in a comment to this question:正如@philipxy 在对这个问题的评论中所写:
Constraints (including FKs & PKs) need not hold, be declared or be known in order to record or query.
约束(包括 FK 和 PK)不需要为了记录或查询而保持、声明或知道。 Joins are binary, the left table is the result of any previous joins in a series without parentheses.
联接是二进制的,左表是没有括号的系列中任何先前联接的结果。 Except for output column order, inner & cross joins have no direction, t join u on c is u join t on c.
除了输出列顺序,内联和交叉联结没有方向,t join u on c 是 u join t on c。
So according to the comment, we would form a join between employee
and branch
and another join between employee
and an alias of branch table called branch2
.因此,根据评论,我们将在
employee
和branch
之间形成一个连接,并在employee
和名为branch2
的分支表的别名之间形成另一个连接。 The common confusion here is that most people(including me earlier) think that there is a "direction" of joins, the thing that philipxy covers in his aforementioned comment.这里常见的困惑是大多数人(包括我之前)认为连接有一个“方向”,philipxy 在他的上述评论中涵盖了这一点。
You can write a SQL query which queries the first_name
, last_name
and branch_id
from the employee
table and the branch_name
from the branch
table and forms a join between the two tables on the basis of branch_id
.你可以写一个SQL查询,其查询
first_name
, last_name
和branch_id
从employee
表和branch_name
从branch
表和形成的基础上,这两个表之间的联接branch_id
。 You have to query the mgr_id
from the alias of the branch table called branch2
;您必须从名为
branch2
的分支表的别名中查询mgr_id
; you have to query the first_name
and the last_name
of the branch managers from the employee table.您必须从员工表中查询分公司经理的
first_name
和last_name
。 You can easily join the employee and the branch table on the basis of emp_id
such that the mgr_id
= emp_id
.您可以根据
emp_id
轻松加入员工和分支表,这样mgr_id
= emp_id
。
You can finally write the SQL query for the problem like this:您最终可以为该问题编写 SQL 查询,如下所示:
SELECT employee.first_name, employee.last_name, employee.branch_id,
branch.branch_name,
branch2.mgr_id, employee.first_name AS manager_first_name, employee.last_name AS manager_last_name
FROM employee
JOIN branch ON employee.branch_id=branch.branch_id
JOIN branch branch2 ON branch2.mgr_id=employee.emp_id;
The above mentioned query would return this:上面提到的查询将返回:
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
| first_name | last_name | branch_id | branch_name | mgr_id | manager_first_name | manager_last_name |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
| David | Wallace | 1 | Corporate | 100 | David | Wallace |
| Michael | Scott | 2 | Scranton | 102 | Michael | Scott |
| Josh | Porter | 3 | Stamford | 106 | Josh | Porter |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
These results might look useless as we have formed an INNER JOIN
between the tables so it just returns us the name of the employees who are "managers" of a specific branch.这些结果可能看起来毫无用处,因为我们在表之间形成了
INNER JOIN
,因此它只返回作为特定分支“经理”的员工的姓名。 If you form a LEFT JOIN
between the tables instead of an INNER JOIN
you would get results like this:如果您在表之间形成
LEFT JOIN
而不是INNER JOIN
您将获得如下结果:
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
| first_name | last_name | branch_id | branch_name | mgr_id | manager_first_name | manager_last_name |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
| David | Wallace | 1 | Corporate | 100 | David | Wallace |
| Jan | Levinson | 1 | Corporate | NULL | Jan | Levinson |
| Michael | Scott | 2 | Scranton | 102 | Michael | Scott |
| Angela | Martin | 2 | Scranton | NULL | Angela | Martin |
| Kelly | Kapoor | 2 | Scranton | NULL | Kelly | Kapoor |
| Stanley | Hudson | 2 | Scranton | NULL | Stanley | Hudson |
| Josh | Porter | 3 | Stamford | 106 | Josh | Porter |
| Andy | Bernard | 3 | Stamford | NULL | Andy | Bernard |
| Jim | Halpert | 3 | Stamford | NULL | Jim | Halpert |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
These results were not as expected as the employees who are not managers of any branch just have a mgr_id
with NULL
value whereas the branch that they word in actually has a manager.这些结果并不像预期的那样,因为不是任何分支机构经理的员工只有一个带有
NULL
值的mgr_id
,而他们mgr_id
的分支机构实际上有一个经理。 With the mgr_id
being NULL, the manager_first_name
and manager_last_name
have unexpected results too.由于
mgr_id
为 NULL, manager_first_name
和manager_last_name
也有意想不到的结果。
The above occurs because we cannot have the same manager for two employees because mgr_id
can not be the same accross rows as it is the emp_id
which is the PRIMARY KEY of the employee
table.发生上述情况是因为我们不能为两个员工使用相同的经理,因为
mgr_id
不能mgr_id
相同,因为它是emp_id
,它是employee
表的主键。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.