在阅读它之后,这不是显式与隐式SQL连接的副本。 答案可能相关(甚至相同),但问题是不同的。


它们之间有什么不同?每一种都应该有什么不同?

如果我正确地理解了这个理论,那么查询优化器应该能够互换地使用这两种方法。


当前回答

这就是我的解。

SELECT song_ID,songs.fullname, singers.fullname
FROM music JOIN songs ON songs.ID = music.song_ID  
JOIN singers ON singers.ID = music.singer_ID
GROUP BY songs.fullname

你必须有GROUP BY才能让它工作。

希望这对你有所帮助。

其他回答

对于内部连接,WHERE和ON可以互换使用。事实上,可以在相关子查询中使用ON。例如:

update mytable
set myscore=100
where exists (
select 1 from table1
inner join table2
on (table2.key = mytable.key)
inner join table3
on (table3.key = table2.key and table3.key = table1.key)
...
)

这(恕我直言)完全让人困惑,而且很容易忘记将table1链接到任何东西(因为“driver”表没有“on”子句),但这是合法的。

从字面上看,它们是等价的。

在大多数开源数据库(最著名的例子是MySql和postgresql)中,查询计划是出现在关系数据库管理系统中的访问路径选择(Selinger et al, 1979)中的经典算法的变体。在这种方法中,条件有两种类型

引用单个表的条件(用于筛选) 引用两个表的条件(不管它们出现在哪里,都被视为连接条件)

特别是在MySql中,通过跟踪优化器,您可以看到自己的join ..On条件在解析过程中被等价的where条件替换。类似的事情也发生在postgresql中(虽然没有办法通过日志看到它,你必须阅读源代码描述)。

无论如何,主要的一点是,这两种语法变体之间的差异在解析/查询-重写阶段就消失了,甚至没有达到查询计划和执行阶段。因此,就性能而言,它们是否相同是毫无疑问的,它们在进入执行阶段之前就已经完全相同了。

你可以用explain来验证他们的计划是否相同。例如,在postgres中,计划将包含一个join子句,即使你没有在语法中使用join..on。

Oracle和SQL server不是开源的,但是,据我所知,它们基于等价规则(类似于关系代数中的规则),并且它们在这两种情况下也产生相同的执行计划。

显然,对于外部连接,这两种语法风格是不相等的,对于那些你必须使用join…在语法

在INNER join中,它们是可互换的,优化器会随意重新排列它们。

在OUTER连接上,它们不一定是可互换的,这取决于它们所依赖的连接的哪一侧。

我把它们放在任意一个位置,取决于可读性。

就优化器而言,使用ON或WHERE定义连接子句应该没有区别。

然而,恕我直言,我认为在执行连接时使用ON子句更清楚。这样,您就有了查询的特定部分,该部分规定了如何处理连接,而不是与其余WHERE子句混合。

a. WHERE子句:加入后,记录将被过滤。

b. ON子句-在加入之前,记录(来自右边表格)将被过滤。