MySQL 5.7与8.0中带括号派生表的SQL语法差异问题
问题详情
数据库中有两张表:
b (b1 INT) c (c1 INT)
在MySQL 5.7中可正常执行的查询语句:
SELECT * FROM b JOIN ((SELECT * FROM c) tmp) ON b.b1 = tmp.c1
但在MySQL 8.0中执行该语句会触发语法错误:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ON b.b1 = TMP.c1 LIMIT 0, 1000' at line 1
去掉一层括号后,语句可在MySQL 8.0中正常执行:
SELECT * FROM b JOIN (SELECT * FROM c) tmp ON b.b1 = tmp.c1
查阅MySQL官方升级文档未找到相关语法变更说明,疑问该情况是语法变更还是bug。
解答
这是MySQL 8.0对语法解析规则的严谨化处理,并非bug。
SQL标准规定,JOIN子句中引用派生表时,仅需一层括号包裹子查询并指定别名,即(SELECT ...) alias的格式。MySQL 5.7对语法兼容性要求更宽松,允许额外的冗余外层括号(即((SELECT ...) alias)这种写法),但该写法并不符合SQL标准。
MySQL 8.0在语法解析器上做了对齐标准的优化,严格遵循SQL规范,不再支持这种冗余括号的写法。官方升级文档未单独提及该细节,是因为它属于解析器的严谨化改进,而非重大功能或语法变更。
你修改后的语句符合SQL标准,可在MySQL 5.7和8.0版本中兼容运行。
内容的提问来源于stack exchange,提问作者Ryannnnnnnnn
相关产品推荐
相关产品推荐

