[英]How to make two joins between two tables in MySQL such that they are interlinked to each other?
我在名为employee
和branch
的公司数据库中有两个表,每个表都有一个外键。 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 | |
+------------+-------------+------+-----+---------+----------------+
分支表如下所示:
+----------------+-------------+------+-----+---------+-------+
| 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 | |
+----------------+-------------+------+-----+---------+-------+
在employee表中, branch_id
外键引用了branch
表的branch_id
。 在分支表中, manager_id
外键引用employee_id
中的employee
表。
我会以循环方式(非正式地说)在这两个表之间形成两个连接,这样employee.branch_id
与branch.branch_id
形成连接,并且branch.manager_id
与employee.employee_id
形成连接。
所以我希望这两个连接的查询返回的是:
employee.first_name AS employee_name, employee.branch_id, branch.branch_name, branch.manager_id, employee.employee_id AS manager_name
我想不出这个问题的可能解决方案,因为每个连接中的 LEFT 表是不同的,而且我不知道如何在单个 SQL 查询中为每个连接定义多个 LEFT 表。
数据库管理系统:MySQL v8.0.26
PS:我的问题与上述问题中的这个问题不同,两个连接的 LEFT 表是相同的,而在我的情况下,它不是。
通过使用表别名,可以在两列之间形成两个连接。 如题所述,在employee
和branch
表之间要形成一个join,在branch
和employee
表之间需要形成另一个join。 这些类型的连接有点棘手的部分是在连接两个表的ON
关键字之后指定的关系。
正如@philipxy 在对这个问题的评论中所写:
约束(包括 FK 和 PK)不需要为了记录或查询而保持、声明或知道。 联接是二进制的,左表是没有括号的系列中任何先前联接的结果。 除了输出列顺序,内联和交叉联结没有方向,t join u on c 是 u join t on c。
因此,根据评论,我们将在employee
和branch
之间形成一个连接,并在employee
和名为branch2
的分支表的别名之间形成另一个连接。 这里常见的困惑是大多数人(包括我之前)认为连接有一个“方向”,philipxy 在他的上述评论中涵盖了这一点。
你可以写一个SQL查询,其查询first_name
, last_name
和branch_id
从employee
表和branch_name
从branch
表和形成的基础上,这两个表之间的联接branch_id
。 您必须从名为branch2
的分支表的别名中查询mgr_id
; 您必须从员工表中查询分公司经理的first_name
和last_name
。 您可以根据emp_id
轻松加入员工和分支表,这样mgr_id
= emp_id
。
您最终可以为该问题编写 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;
上面提到的查询将返回:
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
| 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 |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
这些结果可能看起来毫无用处,因为我们在表之间形成了INNER JOIN
,因此它只返回作为特定分支“经理”的员工的姓名。 如果您在表之间形成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 |
+------------+-----------+-----------+-------------+--------+--------------------+-------------------+
这些结果并不像预期的那样,因为不是任何分支机构经理的员工只有一个带有NULL
值的mgr_id
,而他们mgr_id
的分支机构实际上有一个经理。 由于mgr_id
为 NULL, manager_first_name
和manager_last_name
也有意想不到的结果。
发生上述情况是因为我们不能为两个员工使用相同的经理,因为mgr_id
不能mgr_id
相同,因为它是emp_id
,它是employee
表的主键。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.