内部加入自加入 - MySql
Inner join in self join - MySql
在 Stack Overflow 上提出了以下问题:
“我需要在此 table 上使用 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
INNER JOIN table1 AS b
on a.Year=b.Year
and b.Country='Turkey';
我没有收到此查询。是不是 a.Year=b.Year
总是正确的——因为两个 table 是一样的?那么使用它有什么必要呢?
而且上面的查询不是只会return国内'Turkey'吗?
如有错误请大家指正。
非常感谢!
如果你必须在这里使用自连接,那么试试这个:
SELECT t1.Country, t1.Year
FROM table1 t1
INNER JOIN table1 t2
ON t1.Year = t2.Year AND t2.Country = 'Turkey';
这不是我认为的自连接查询的典型候选对象。在这种情况下,第二个(右)table 只是代表土耳其的年份。
我宁愿只使用子查询:
SELECT Country, Year
FROM table1
WHERE Year = (SELECT Year FROM table1 WHERE Country = 'Turkey');
请注意,这还将在结果集中包括土耳其本身。如果你不想也看到土耳其,那么我们可以在WHERE
子句中添加另一个条件:
SELECT Country, Year
FROM table1
WHERE Year = (SELECT Year FROM table1 WHERE Country = 'Turkey') AND Country <> 'Turkey';
Isn't it that a.Year=b.Year always going to be true?
没有。将此视为首先采用 A 和 B 的笛卡尔积(将 a 的所有行与 b 的所有行匹配),然后选择 a 的年份和 B 的年份相同的那些行。这会产生两个国家相同年份的数据。
使用这些数据我们可以进一步确定与土耳其组成一对的国家。
这就是这个查询正在做的事情。
请记住,您正在加入 行。 WHERE
子句和 ON
子句每次总是引用每个 table 的特定行。此伪代码显示了连接中实际发生的情况:
foreach a = row of table1
if a.country = 'Turkey' then
foreach b = row of table1
if b.year = a.year then
keep the joined row
endif
endloop
endif
endloop
(DBMS可能使用另一种匹配记录的方法。但是你可以像上面那样想象。)
在 Stack Overflow 上提出了以下问题:
“我需要在此 table 上使用 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
INNER JOIN table1 AS b
on a.Year=b.Year
and b.Country='Turkey';
我没有收到此查询。是不是 a.Year=b.Year
总是正确的——因为两个 table 是一样的?那么使用它有什么必要呢?
而且上面的查询不是只会return国内'Turkey'吗?
如有错误请大家指正。
非常感谢!
如果你必须在这里使用自连接,那么试试这个:
SELECT t1.Country, t1.Year
FROM table1 t1
INNER JOIN table1 t2
ON t1.Year = t2.Year AND t2.Country = 'Turkey';
这不是我认为的自连接查询的典型候选对象。在这种情况下,第二个(右)table 只是代表土耳其的年份。
我宁愿只使用子查询:
SELECT Country, Year
FROM table1
WHERE Year = (SELECT Year FROM table1 WHERE Country = 'Turkey');
请注意,这还将在结果集中包括土耳其本身。如果你不想也看到土耳其,那么我们可以在WHERE
子句中添加另一个条件:
SELECT Country, Year
FROM table1
WHERE Year = (SELECT Year FROM table1 WHERE Country = 'Turkey') AND Country <> 'Turkey';
Isn't it that a.Year=b.Year always going to be true?
没有。将此视为首先采用 A 和 B 的笛卡尔积(将 a 的所有行与 b 的所有行匹配),然后选择 a 的年份和 B 的年份相同的那些行。这会产生两个国家相同年份的数据。
使用这些数据我们可以进一步确定与土耳其组成一对的国家。
这就是这个查询正在做的事情。
请记住,您正在加入 行。 WHERE
子句和 ON
子句每次总是引用每个 table 的特定行。此伪代码显示了连接中实际发生的情况:
foreach a = row of table1
if a.country = 'Turkey' then
foreach b = row of table1
if b.year = a.year then
keep the joined row
endif
endloop
endif
endloop
(DBMS可能使用另一种匹配记录的方法。但是你可以像上面那样想象。)