自我加入
表可以连接到自身,其中不同的行通过某种条件彼此匹配。在此用例中,必须使用别名以区分表的两次出现。
在下面的示例中,对于示例数据库 Employees 表中的每个 Employee,将返回一条记录,其中包含员工的名字以及员工经理的相应名字。由于经理也是员工,因此表格与自身相结合:
SELECT
e.FName AS "Employee",
m.FName AS "Manager"
FROM
Employees e
JOIN
Employees m
ON e.ManagerId = m.Id
此查询将返回以下数据:
| 雇员 | 经理 |
|---|---|
| 约翰 | 詹姆士 |
| 迈克尔 | 詹姆士 |
| 乔纳森 | 约翰 |
那怎么办?
原始表包含以下记录:
ID |
FName 参数 | LName | 电话号码 | 经理 ID | DepartmentID | 薪水 | 聘用日期 |
|---|---|---|---|---|---|---|---|
1 |
詹姆士 | 工匠 | 1234567890 | 空值 | 1 | 1000 | 2002 年 1 月 1 日 |
2 |
约翰 | 约翰逊 | 2468101214 | 1 | 1 | 400 | 23-03-2005 |
3 |
迈克尔 | 威廉姆斯 | 1357911131 | 1 | 2 | 600 | 12-05-2009 |
4 |
乔纳森 | 工匠 | 1212121212 | 2 | 1 | 500 | 24-07-2016 |
第一个操作是创建 FROM 子句中使用的表中所有记录的笛卡尔积。在这种情况下,它是两次 Employees 表,因此中间表将如下所示(我删除了此示例中未使用的任何字段): ****
| e.Id | e.FName | e.ManagerId | 中 | m.FName | m.ManagerId |
|---|---|---|---|---|---|
1 |
詹姆士 | 空值 | 1 | 詹姆士 | 空值 |
1 |
詹姆士 | 空值 | 2 | 约翰 | 1 |
1 |
詹姆士 | 空值 | 3 | 迈克尔 | 1 |
1 |
詹姆士 | 空值 | 4 | 乔纳森 | 2 |
2 |
约翰 | 1 | 1 | 詹姆士 | 空值 |
2 |
约翰 | 1 | 2 | 约翰 | 1 |
2 |
约翰 | 1 | 3 | 迈克尔 | 1 |
2 |
约翰 | 1 | 4 | 乔纳森 | 2 |
3 |
迈克尔 | 1 | 1 | 詹姆士 | 空值 |
3 |
迈克尔 | 1 | 2 | 约翰 | 1 |
3 |
迈克尔 | 1 | 3 | 迈克尔 | 1 |
3 |
迈克尔 | 1 | 4 | 乔纳森 | 2 |
4 |
乔纳森 | 2 | 1 | 詹姆士 | 空值 |
4 |
乔纳森 | 2 | 2 | 约翰 | 1 |
4 |
乔纳森 | 2 | 3 | 迈克尔 | 1 |
4 |
乔纳森 | 2 | 4 | 乔纳森 | 2 |
下一步操作是仅保留符合 JOIN 条件的记录,因此别名 e 表 ManagerId 等于别名 m 表 Id 的任何记录:
| e.Id | e.FName | e.ManagerId | 中 | m.FName | m.ManagerId |
|---|---|---|---|---|---|
2 |
约翰 | 1 | 1 | 詹姆士 | 空值 |
3 |
迈克尔 | 1 | 1 | 詹姆士 | 空值 |
4 |
乔纳森 | 2 | 2 | 约翰 | 1 |
然后,评估 SELECT 子句中使用的每个表达式以返回此表:
| e.FName | m.FName |
|---|---|
| 约翰 | 詹姆士 |
| 迈克尔 | 詹姆士 |
| 乔纳森 | 约翰 |
最后,列名称 e.FName 和 m.FName 由其别名列名替换,并使用 AS 运算符分配 :
| 雇员 | 经理 |
|---|---|
| 约翰 | 詹姆士 |
| 迈克尔 | 詹姆士 |
| 乔纳森 | 约翰 |