MySQL的。如何使用自我加入

时间:2013-05-22 21:32:40

标签: mysql sql self-join

我需要在这张桌子上使用自我加入。

+------------+------+--------+
| Country    | Rank |  Year  |
+------------+------+--------+
|France      |  55  |  2000  |
+------------+------+--------+
|Canada      |  30  |  2000  |
+------------+------+--------+ 
|Liberia     |  59  |  2001  |
+------------+------+--------+ 
|Turkey      |  78  |  2000  |
+------------+------+--------+ 
|Japan       |  65  |  2003  |
+------------+------+--------+
|Romania     |  107 |  2001  |
+------------+------+--------+

我需要使用自我加入来获得与土耳其同年的国家。 仅显示国家/地区和年份。

这就是我想要做的。

SELECT DISTINCT a.Country, a.Year 
FROM table1 AS a, table1 AS b 
WHERE a.Year=b.Year and a.Country='Turkey';

^ googled self join,并成功。

我只得到土耳其。我做错了什么?

3 个答案:

答案 0 :(得分:14)

你真是太近了!

既然你说你正在显示来自A的国家和年份并且被土耳其A. Country限制,那么土耳其就是你要看到的。您需要将选择更改为B.countryB.year,或将where子句更改为B.country

这是使用交叉连接,这会使表中的记录越多越慢。

SELECT DISTINCT b.Country, b.Year 
FROM table1 AS a, 
     table1 AS b 
WHERE a.Year=b.Year 
  and a.Country='Turkey';

可以写成......并且可能会有相同的执行计划。

SELECT DISTINCT b.Country, b.Year 
FROM table1 AS a 
CROSS JOIN table1 AS b 
WHERE a.Year=b.Year 
  and a.Country='Turkey';

OR 这使用INNER JOIN来限制引擎必须执行的工作,并且不会受到交叉连接的性能下降的影响。

SELECT DISTINCT a.Country, a.Year 
FROM table1 AS a 
INNER JOIN table1 AS b 
   on a.Year=b.Year 
  and b.Country='Turkey';

为什么:

考虑连接发生时SQL引擎将执行的操作      A B

+------------+------+--------+------------+------+--------+
| A.Country  | Rank |  Year  | B.Country  | Rank |  Year  |
+------------+------+--------+------------+------+--------+
|France      |  55  |  2000  |France      |  55  |  2000  |
+------------+------+--------+------------+------+--------+
|Canada      |  30  |  2000  |France      |  55  |  2000  |
+------------+------+--------+------------+------+--------+ 
|Turkey      |  78  |  2000  |France      |  55  |  2000  |
+------------+------+--------+------------+------+--------+ 
|France      |  55  |  2000  |Canada      |  30  |  2000  |
+------------+------+--------+------------+------+--------+
|Canada      |  30  |  2000  |Canada      |  30  |  2000  |
+------------+------+--------+------------+------+--------+ 
|Turkey      |  78  |  2000  |Canada      |  30  |  2000  |
+------------+------+--------+------------+------+--------+ 
|France      |  55  |  2000  |Turkey      |  78  |  2000  |
+------------+------+--------+------------+------+--------+
|Canada      |  30  |  2000  |Turkey      |  78  |  2000  |
+------------+------+--------+------------+------+--------+ 
|Turkey      |  78  |  2000  |Turkey      |  78  |  2000  |
+------------+------+--------+------------+------+--------+ 

所以当你说显示A.CountryA.Year A.Country是土耳其时,你可以看到它可以返回的是土耳其(由于仅有1条记录)

但是如果你B.Country是土耳其并展示A.Country,那么你将获得法国,加拿大和土耳其!

答案 1 :(得分:5)

a.Country = 'Turkey'更改为b.Country = 'Turkey'

您有SELECT DISTINCT a.Country,但您的条件是a.Country = 'Turkey'。即使您确实获得了多行,也会按DISTINCT

进行过滤

答案 2 :(得分:0)

select distinct country,year from table1 where year=(select year from table  
where country='turkey') and country !=turkey;