簡體   English   中英

如何在 MySQL 中的兩個表之間進行兩個連接,使它們相互關聯?

[英]How to make two joins between two tables in MySQL such that they are interlinked to each other?

我在名為employeebranch的公司數據庫中有兩個表,每個表都有一個外鍵。 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_idbranch.branch_id形成連接,並且branch.manager_idemployee.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 表是相同的,而在我的情況下,它不是。

如何着手解決問題

通過使用表別名,可以在兩列之間形成兩個連接。 如題所述,在employeebranch表之間要形成一個join,在branchemployee表之間需要形成另一個join。 這些類型的連接有點棘手的部分是在連接兩個表的ON關鍵字之后指定的關系。

正如@philipxy 在對這個問題的評論中所寫:

約束(包括 FK 和 PK)不需要為了記錄或查詢而保持、聲明或知道。 聯接是二進制的,左表是沒有括號的系列中任何先前聯接的結果。 除了輸出列順序,內聯和交叉聯結沒有方向,t join u on c 是 u join t on c。

因此,根據評論,我們將在employeebranch之間形成一個連接,並在employee和名為branch2的分支表的別名之間形成另一個連接。 這里常見的困惑是大多數人(包括我之前)認為連接有一個“方向”,philipxy 在他的上述評論中涵蓋了這一點。

問題的解決方案

你可以寫一個SQL查詢,其查詢first_namelast_namebranch_idemployee表和branch_namebranch表和形成的基礎上,這兩個表之間的聯接branch_id 您必須從名為branch2的分支表的別名中查詢mgr_id 您必須從員工表中查詢分公司經理的first_namelast_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_namemanager_last_name也有意想不到的結果。

發生上述情況是因為我們不能為兩個員工使用相同的經理,因為mgr_id不能mgr_id相同,因為它是emp_id ,它是employee表的主鍵。

學分

  • @philpxy 對這個問題的評論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM