我在SQLZOO练习自我加入,这是我对以下问题(Q10)不理解的事情:
问题是: 查找包含两条巴士的路线,从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,那么这里的连接条件是什么?这次加入的结果是什么?
答案 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中,关键字INNER
和CROSS
是可选的,并且没有影响力。也就是说,JOIN
和INNER JOIN
以及CROSS JOIN
都是同义词。因此,我们的使用方式与其他数据库的兼容性有所了解,并且注意到未来的读者可能试图破译我们的陈述。