我在一個名為公司資料庫中的兩個表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 | |
---------------- ------------- ------ ----- --------- -------
在雇員表中,branch_id外鍵參考branch_id了的branch表。在分支表中,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 表是相同的,而在我的情況下,它不是。
uj5u.com熱心網友回復:
如何著手解決問題
通過使用表別名,可以在兩列之間形成兩個連接。作為問題指定,即加入一個將要在之間形成employee和branch表中,而另一個連接需要在之間形成branch和employee表。這些型別的連接有點棘手的部分是在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。您必須mgr_id從名為branch2;的分支表的別名中查詢 你要查詢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在表之間形成 a而不是 aINNER 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 |
------------ ----------- ----------- ------------- -------- -------------------- -------------------
這些結果并不如預期誰是不是任何分行經理的員工只是有一個mgr_id具有NULL價值,而他們中的字居然有一個經理的分支。由于mgr_id為 NULL,manager_first_name和manager_last_name也有意想不到的結果。
發生上述情況是因為我們不能為兩個員工使用相同的經理,因為mgr_id跨行不能相同,因為它是表emp_id的主鍵employee。
學分
- @philpxy 's comments on this question
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/336005.html
