自我加入
表可以连接到自身,其中不同的行通过某种条件彼此匹配。在此用例中,必须使用别名以区分表的两次出现。
在下面的示例中,对于示例数据库 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 运算符分配 :
雇员 | 经理 |
---|---|
约翰 | 詹姆士 |
迈克尔 | 詹姆士 |
乔纳森 | 约翰 |