内联接自联接-MySql

时间:2018-10-23 05:03:52

标签: mysql 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始终都是正确的-因为两个表都相同吗?那么使用它有什么需要呢? 难道上述查询将在该国家/地区仅返回“土耳其”吗?

如果我写错了,请帮助我。

非常感谢!

3 个答案:

答案 0 :(得分:0)

如果您必须在此处使用自连接,请尝试以下操作:

SELECT t1.Country, t1.Year
FROM table1 t1
INNER JOIN table1 t2
    ON t1.Year = t2.Year AND t2.Country = 'Turkey';

enter image description here

Demo

这不是我认为是自联接查询的典型候选对象。在这种情况下,第二个(右)表仅代表土耳其的年份。

我宁愿只使用子查询:

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';

答案 1 :(得分:0)

  

不是a.Year = b.Year总是正确的吗?

不。可以认为这是首先取A和B的笛卡尔积(将a的所有行与b的所有行匹配),然后选择a年和B年相同的那些行。这将得出两个国家具有相同年份的数据。

使用这些数据,我们可以进一步确定与土耳其结对的国家/地区。

这就是查询的作用。

答案 2 :(得分:0)

请记住,您正在加入WHERE子句和ON子句总是一次引用每个表的特定行。此伪代码显示了联接中实际发生的情况:

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可以使用另一种匹配记录的方法。但是您可以像上面想象的那样。)