Error number: 3973; Symbol: ER_SUBQUERY_TRANSFORM_REJECTED; SQLSTATE: HY000
Message: Statement requires a transform of a subquery to a non-SET operation (like IN2EXISTS, or subquery-to-LATERAL-derived-table). This is not allowed with optimizer switch ‘subquery_to_derived’ on
ER_SUBQUERY_TRANSFORM_REJECTED错误码为3973,其SQLSTATE为HY000。该错误指出无法将查询转换为子查询形式,这一般情况下发生在包含多个子查询的查询中,表明这些子查询的结构不允许进行转换。
当MySQL尝试转换使用多个表的LEFT OUTER JOIN查询,这些查询可能包含别名,等等时,这个错误就可能发生。另外一种概率较大的发生场景是,当尝试转换一个查询时,MySQL可能会因为安全原因而拒绝这样做。
假设一名MySQL用户计划从一或多个表中查询数据,此查询将多个子查询包装在一起,尝试像下面这样执行:
SELECT * FROM T1 LEFT OUTER JOIN
(SELECT * FROM T2 LEFT OUTER JOIN
(SELECT * FROM T3) AS T3
ON T2.id=T3.id) AS t2
ON t1.id=t2.id;
上述查询有可能会出现ER_SUBQUERY_TRANSFORM_REJECTED错误,因为这个查询无法进行转换。
解决方法:
对于出现ER_SUBQUERY_TRANSFORM_REJECTED错误,可以试着消除查询中的子查询并改用JOIN语句。如果查询是由多张表关联实现,可能需要多个JOIN语句来替换子查询;而如果查询包含多个别名,可能需要在语句中多次指定表名。
同时,实际编写比较复杂的查询时,应当将查询逐步进行,确定子查询可以独立执行,将大查询分解为多个小查询,以此减少出错的概率,也可以帮助MySQL优化执行计划。
此外,当识别查询可能发生报错时,也可以试着使用不同的写法,比如更改查询结构,添加联接或者#印号,来改善查询的结构,从而避免报错。