一个表可以连接到自身,而不同的行在某种条件下彼此匹配。在这种情况下,必须使用别名以区分表的两次出现。
在下面的示例中,对于示例数据库“雇员”表中的每个“雇员”,将返回一条记录,其中包含该雇员的名字以及该雇员的经理的相应名字。由于经理也是员工,因此该表将自身结合在一起:
SELECT e.FNameAS "Employee", m.FNameAS "Manager" FROM Employees e JOIN Employees m ONe.ManagerId= m.Id
该查询将返回以下数据:
雇员 | 经理 |
---|---|
约翰 | 詹姆士 |
麦可 | 詹姆士 |
约翰松 | 约翰 |
原始表包含以下记录:
ID | 姓名 | 名称 | 号码 | ManagerId | 部门编号 | 薪水 | 雇用日期 |
---|---|---|---|---|---|---|---|
1 | 詹姆士 | 史密斯 | 1234567890 | 空值 | 1 | 1000 | 2002年1月1日 |
2 | 约翰 | 约翰逊 | 2468101214 | 1 | 1 | 400 | 2005年3月23日 |
3 | 麦可 | 威廉姆斯 | 1357911131 | 1 | 2 | 600 | 2009年12月5日 |
4 | 约翰松 | 史密斯 | 1212121212 | 2 | 1 | 500 | 2016年7月24日 |
第一步是为FROM子句中使用的表中的所有记录创建笛卡尔乘积。在这种情况下,它是雇员表两次,因此中间表将如下所示(我删除了此示例中未使用的任何字段):
编号 | e.FName | e.ManagerId | 中 | 名 | 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.FName | e.ManagerId | 中 | 名 | m.ManagerId |
---|---|---|---|---|---|
2 | 约翰 | 1 | 1 | 詹姆士 | 空值 |
3 | 麦可 | 1 | 1 | 詹姆士 | 空值 |
4 | 约翰松 | 2 | 2 | 约翰 | 1 |
然后,对SELECT子句中使用的每个表达式求值以返回该表:
e.FName | 名 |
---|---|
约翰 | 詹姆士 |
麦可 | 詹姆士 |
约翰松 | 约翰 |
最后,用AS运算符分配的列名e.FName和m.FName被其别名列名替换:
雇员 | 经理 |
---|---|
约翰 | 詹姆士 |
麦可 | 詹姆士 |
约翰松 | 约翰 |