mysql

ghhkc1vu  于 2021-06-19  发布在  Mysql
关注(0)|答案(3)|浏览(273)

关于堆栈溢出,提出了以下问题:
“我需要在这个表上使用self-join。

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

我需要使用self-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';

我不明白这个问题。不是吗 a.Year=b.Year 总是会是真的-因为两张table是一样的?那么使用它有什么必要呢?上面的查询不是只返回土耳其吗?
如果我错了,请帮助我理解。
谢谢!

sg24os4d

sg24os4d1#

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

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

演示

我认为这不是自连接查询的典型候选。在本例中,第二个(右)表仅用于表示土耳其拥有的年份。
我宁愿只使用子查询:

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

t30tvxxf2#

a.year=b.year不是一直都是真的吗?
不可以。可以这样想:首先取a和b的笛卡尔积(将a的所有行与b的所有行匹配),然后选择a的年份和b的年份相同的行。这就产生了两个国家同一年的数据。
利用这些数据,我们可以进一步确定与土耳其结成一对的国家。
这就是这个查询所做的。

qxsslcnc

qxsslcnc3#

请记住,您正在加入行。 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可以使用另一种方法来匹配记录。但你可以想像上面那样。)

相关问题