逗号分隔的连接和MySQL中的语法连接有啥区别? [复制]

Posted

技术标签:

【中文标题】逗号分隔的连接和MySQL中的语法连接有啥区别? [复制]【英文标题】:What's the difference between comma separated joins and join on syntax in MySQL? [duplicate]逗号分隔的连接和MySQL中的语法连接有什么区别? [复制] 【发布时间】:2013-12-06 22:46:58 【问题描述】:

例如,如果我有一个表“Person”,其中的列“id”引用表“Worker”中的列“id”

这两个查询有什么区别?它们产生相同的结果。

SELECT * 
FROM Person 
JOIN Worker 
  ON Person.id = Worker.id;

SELECT * 
FROM Person, 
     Worker 
WHERE Person.id = Worker.id;

谢谢

【问题讨论】:

逗号的优先级低于关键字 JOIN。 【参考方案1】:

完全没有区别

第一种表示形式使查询更具可读性,并且使哪个连接对应于哪个条件看起来非常清晰。

【讨论】:

性能上绝对没有差别。 SQL Server 准备的最终版本在这两种情况下都是相同的。 对于较大的查询,我会说第一种方式更具可读性。如果您有混合左连接和一些内连接,那么在连接子句中使用连接条件会更加一致,而不是在连接中有一些在 where 子句中。 第一个更易读和明确 这个答案不正确。在dev.mysql.com/doc/refman/5.5/en/join.html 页上的 MySQL 手册中指出:“但是,逗号运算符的优先级低于 INNER JOIN、CROSS JOIN、LEFT JOIN 等。如果将逗号连接与其他连接类型混合使用当存在连接条件时,可能会出现“onclause”中的“Unknown column 'col_name'形式的错误” @CaptainPayalytic:问题中给出的两个查询在逻辑上是等价的。正如您所指出的,这两种符号之间实际上存在差异。 (我同意你的观点,这个答案是错误的。事实上,两个查询之间存在差异......我们可以说一个使用老式逗号语法进行连接操作,其他使用 JOIN 关键字。)【参考方案2】:

查询在逻辑上是等价的。逗号运算符等价于[INNER] JOIN 运算符。

逗号是旧式连接运算符。 JOIN 关键字是后来添加的,并且由于它还允许 OUTER 连接操作而受到青睐。

它还允许将连接谓词(条件)从WHERE 子句中分离到ON 子句中。这提高了(人类)可读性。


跟进

这个答案说问题中的两个查询是等价的。我们不应该在同一个查询中将用于连接操作的老式逗号语法与较新的 JOIN 关键字语法混合在一起。如果我们确实将它们混合在一起,我们需要注意优先顺序的不同。

摘自 MySQL 参考手册

https://dev.mysql.com/doc/refman/5.6/en/join.html

INNER JOIN,(逗号)在没有连接条件的情况下在语义上是等价的:两者都在指定的表之间产生笛卡尔积(也就是说,第一个表中的每一行都连接到每个表,并且第二个表中的每一行)。

但是,逗号运算符的优先级低于INNER JOINCROSS JOINLEFT JOIN 等。如果在存在连接条件时将逗号连接与其他连接类型混合使用,则可能会出现Unknown column 'col_name' in 'on clause' 形式的错误。本节稍后会提供有关处理此问题的信息。

【讨论】:

逗号是 CROSS JOIN 或 INNER JOIN ON 1=1。它的优先级低于关键字连接。 INNER JOIN ON 用逗号 & WHERE 定义。【参考方案3】:

使用 JOINS 使代码更易于阅读,因为它是不言自明的。

在速度上没有区别(我测试过),执行计划是一样的

如果查询优化器正常工作,那么这些查询之间应该没有区别。它们只是指定相同期望结果的两种方法。

【讨论】:

更容易阅读是一个很好的解释。代码应该总是写得更容易阅读。我同意你 100%【参考方案4】:

除了更好的可读性之外,还有一种情况是显式连接的表比逗号分隔的表更好。

让我们看一个例子:

Create Table table1
(
    ID int NOT NULL Identity(1, 1) PRIMARY KEY ,
    Name varchar(50)
)

Create Table table2
(
    ID int NOT NULL Identity(1, 1) PRIMARY KEY ,
    ID_Table1 INT NOT NULL
)

以下查询将为我提供两个表中的所有列和行

SELECT
    *
FROM table1, table2

以下查询将为我提供第一个表中的列,表别名为“table2”

SELECT
    *
FROM table1 table2

如果您在逗号分隔连接中错误地忘记了逗号,则第二个表会自动转换为第一个表的表别名。并非在所有情况下,但有这样的机会

【讨论】:

如果 table1table2 不相关,我将这里的 FROM + 逗号语法评为替代且更冗长的 INNER JOIN table2 ON 1 = 1,因为 ON 谓词是多余的。跨度> @MattArnold :对于 MySQL,ON 子句是可选的。 ON 1=1 没有效果并且是不必要的。此外,INNER 关键字是可选的,没有任何作用。即FROM table1 JOIN table2 就足够了,尽管在这种情况下,在 ON 或 WHERE 子句中没有连接条件,我们可以包含可选的 CROSS 关键字作为对未来读者的帮助。帮助读者理解没有连接条件是故意的。即FROM table1 CROSS JOIN table2。我认为这种形式比逗号语法更清楚地传达了我们的意图。【参考方案5】:

The SELECT * FROM table1, table2, etc. 适用于几个表格,但随着表格数量的增加,它变得更加困难。

JOIN 语法明确了哪些条件会影响哪些表(给出条件)。另外,第二种方式是较旧的标准。

虽然,对于数据库,它们最终是相同的

【讨论】:

指数级更难?如何?和谁? @Gal 我认为这只是印度的一种说法,即逗号分隔的表名可以写在一行中...¯\_(ツ)_/¯ 这就是我所能理解的那句话,因为我只是猜测-只有作者才能知道那句话的含义..

以上是关于逗号分隔的连接和MySQL中的语法连接有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MySQL 的多对多关系中以逗号分隔的列表中的一个字段连接数据?

MySQL 查询:连接表并将记录显示为单行中的逗号分隔字符串

左连接和右连接有啥区别

mysql中的左连接和右连接有啥区别[重复]

Mysql 使用逗号分隔列表 - 连接表

MySQL UPDATE语句SET多字段,逗号连接和AND连接的区别