了解多个自我加入

时间:2018-04-01 01:49:56

标签: mysql sql

我在SQLZOO练习自我加入,这是我对以下问题(Q10)不理解的事情:

Two tables look like this

问题是: 查找包含两条巴士的路线,从Craiglockhart到Sighthill。 显示巴士号。和公司的第一辆公共汽车,转移的名称, 和巴士没有。和公司的第二辆公共汽车 答案是:

SELECT DISTINCT a.num, a.company, stopb.name ,  c.num,  c.company
FROM route as a JOIN route as b
ON (a.company = b.company AND a.num = b.num)
JOIN ( route c JOIN route d ON (c.company = d.company AND c.num= d.num))
JOIN stops as stopa ON (a.stop = stopa.id)
JOIN stops as stopb ON (b.stop = stopb.id)
JOIN stops as stopc ON (c.stop = stopc.id)
JOIN stops as stopd ON (d.stop = stopd.id)
WHERE  stopa.name = 'Craiglockhart' AND stopd.name = 'Sighthill'
        AND  stopb.name = stopc.name
ORDER BY LENGTH(a. num), b.num, stopb.id, LENGTH(c.num), d.num

我对

的结果感到很困惑
FROM route a JOIN route b ON (a.company = b.company AND a.num = b.num)
JOIN ( route c JOIN route d ON (c.company = d.company AND c.num= d.num))

第二个JOIN不包含ON,那么这里的连接条件是什么?这次加入的结果是什么?

1 个答案:

答案 0 :(得分:2)

结果是交叉产品。左边的每一行都与右边的每一行相匹配。

对于这种类型的连接,如果没有ON子句,我们通常会在CROSS之前添加JOIN关键字,以提醒未来读者有意省略ON子句,而不是疏忽。

SELECT ...
  FROM a 
 CROSS
  JOIN b
 ORDER BY ...

如果我们指定ON expr的表达式为每一行的计算结果为true,我们得到相同的结果。

SELECT ...
  FROM a 
  JOIN b
    ON 1=1
 ORDER BY ...

结果与我们完全省略ON子句相同......来自a的一行匹配b中的每一行。

在这种情况下,我倾向于省略ON子句(表达式/条件总是求值为TRUE)并指定CROSS JOIN。我认为这使得意图更加明确。

MySQL比其他一些数据库更自由,在省略CROSS子句时需要ON关键字。

在MySQL中,关键字INNERCROSS是可选的,并且没有影响力。也就是说,JOININNER JOIN以及CROSS JOIN都是同义词。因此,我们的使用方式与其他数据库的兼容性有所了解,并且注意到未来的读者可能试图破译我们的陈述。