web-dev-qa-db-ja.com

MySql。自己結合の使用方法

このテーブルで自己結合を使用する必要があります。

+------------+------+--------+
| 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自己結合し、作成しました。

私はトルコだけを手に入れています。私は何が間違っているのですか?

9
hank99

あなたはとても近いです!

Aから国と年を表示し、トルコのA. Countryで制限していると言うので、表示されるのはトルコだけです。 selectをB.countryおよびB.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  |
+------------+------+--------+------------+------+--------+ 

したがって、display A.CountryおよびA.YearA.Countryはトルコ)と言った場合、返されるのはトルコだけであることがわかります(レコードが1つしかないため)。

ただし、B.Countryがトルコで、A.Countryを表示すると、フランス、カナダ、トルコが表示されます。

16
xQbert

変化する a.Country = 'Turkey'からb.Country = 'Turkey'

あなたが持っている SELECT DISTINCT a.Country、しかしあなたの状態はa.Country = 'Turkey'。複数の行を取得した場合でも、それらはDISTINCTによってフィルタリングされます

5
Explosion Pills
select distinct country,year from table1 where year=(select year from table  
where country='turkey') and country !=turkey;
0
griffintaur