了解SQL自联接

时间:2013-03-04 03:59:32

标签: mysql join self-join

我正在尝试理解SQL自连接。我有下表“人员”,其中包含员工的姓名,姓氏,地址和城市(来源W3Schools):

mysql> select * from persons;
+------+-----------+-----------+--------------+-----------+
| P_id | LastName  | FirstName | Address      | City      |
+------+-----------+-----------+--------------+-----------+
|    1 | Hansen    | Ola       | Timoteivn 10 | Sandnes   | 
|    2 | Svendson  | Tove      | Borgvn 23    | Sandnes   |
|    3 | Pettersen | Kari      | Storgt 20    | Stavanger |
+------+-----------+-----------+--------------+-----------+

我现在想要返回与'Hansen Ola'拥有相同城市的员工的姓名。所以我写了一个自我加入,它工作正常:

mysql> select p1.Lastname, p1.firstname from persons p1, persons p2 where p1.city =    p2.city and p2.lastname = 'Hansen';
+----------+-----------+
| Lastname | firstname |
+----------+-----------+
| Hansen   | Ola       |
| Svendson | Tove      |
+----------+-----------+

但是,如果我将别名p2更改为p1,即p2.lastname ='Hansen'更改为p1.lastname ='Hansen',那么我不会获得两个员工的姓名。

mysql> select p1.Lastname, p1.firstname from persons p1, persons p2 where p1.city = p2.city and p1.lastname = 'Hansen';
+----------+-----------+
| Lastname | firstname |
+----------+-----------+
| Hansen   | Ola       |
| Hansen   | Ola       |
+----------+-----------+

有人可以帮助我理解为什么将别名从p2改为p1会改变结果吗?谢谢。

3 个答案:

答案 0 :(得分:1)

查询有点奇怪,我不确定它在现实中有什么基础。本质上,它将一个表与自己的城市列匹配,然后指定其中一个表的lastname,这限制了结果。如果您执行SELECT *而不是仅选择有限的行,则可以看到该表与自身交叉连接,并返回由city和{{1}过滤的行的叉积} 要求。实际结果如下:

lastname

由于条件的反转,原始查询中的情况相反。

答案 1 :(得分:1)

让我突出你的问题,希望它会更有意义:

select p1.lastname, ...
from persons p1, persons p2
where ... and p1.lastname = 'Hansen'

因此,您将结果限制为仅返回第一个表p1中的记录。同时,您将第一个表限制为只有lastname ='Hansen'的表。如果你描绘了无限制的结果集,它可能更有意义(我删除了WHERE子句的粗略部分以显示完整的产品):

select p1.Lastname as p1_lastname, p2.lastname as p2_lastname
from persons p1, persons p2
where p1.city = p2.city

P1_LASTNAME     P2_LASTNAME
Hansen  Hansen
Svendson    Hansen
Hansen  Svendson
Svendson    Svendson
Pettersen   Pettersen

如果您使用上面的结果集并添加条件p1.lastname = "Hansen",那么您只能从中获取'Hansen'并不奇怪。

答案 2 :(得分:0)

您的查询仅返回包含“Hansen”的行。它不跟随自我加入。