[英]Understanding SQL 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会改变结果吗? 谢谢。
查询有点奇怪,我不确定它在现实中的基础。 本质上,它将一个表与自己的城市列匹配,然后指定其中一个表的lastname
,这限制了结果。 如果您执行SELECT *
而不是仅选择有限的行,则可以看到该表正在与自身交叉连接,并且它返回按city
和lastname
要求过滤的行的叉积。 实际结果如下:
p1.firstname, p1.lastname, p2.firstname, p2.lastname
Hansen Ola Hansen Ola
Hansen Ola Svendson Toda
由于条件的反转,这在原始查询中是相反的。
让我突出你的查询,希望它会更有意义:
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'就不足为奇了。
您的查询仅返回包含“Hansen”的行。 它不跟随自我加入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.