11

我需要在这张桌子上使用 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';

^ 谷歌搜索自我加入,并成功了。

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

4

3 回答 3

20

你这么近!

既然您说您要显示来自 A 和限制A. Country的土耳其的国家和年份,那么您将看到的只是土耳其。您需要将选择更改为B.countryandB.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';

或 这使用了一个内部联接,它限制了引擎必须完成的工作,并且不会遭受交叉联接所带来的性能下降。

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 引擎会做什么 AB

+------------+------+--------+------------+------+--------+
| 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.Country和土耳其A.Year在哪里时A.Country,你可以看到它只能返回土耳其(由于唯一的 1 条记录)

但如果你做B.Country的是土耳其和展示A.Country,你会得到法国、加拿大和土耳其!

于 2013-05-22T21:36:55.160 回答
5

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

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

于 2013-05-22T21:34:37.610 回答
0
select distinct country,year from table1 where year=(select year from table  
where country='turkey') and country !=turkey;
于 2015-09-01T14:26:45.603 回答