UPDATE payment_data rr SET rr.penalty_date = '2017-4-12' where rr.id = (SELECT min(r.id) FROM payment_data r where data_no = (SELECT data_no FROM user_debt WHERE out_trade_no = 'bestpay_order_no1491812746329'));
ERROR 1093 (HY000): You can't specify target table 'rr' for update in FROM clause 如果对MySQL查询优化器足够了解就会明白,其实这种方式是MySQL不支持的,有没有WA呢,还是有的,那就是通过一种特殊的子查询来完成,也就是derived table
所以上面的语句使用如下的方式就可以破解。
UPDATE payment_data rr SET rr.penalty_date = '2017-4-12' where rr.id = (SELECT min(t.id) FROM (select id,data_no from payment_data r) t where t.data_no = (SELECT data_no FROM user_debt WHERE out_trade_no = 'bestpay_order_no1491812746329')); 我们回到刚刚提到的Derived table,在官方文档中是这么说的。
第一种:
> select * from (select id from t_fund_info) t where t.id=138031; 1 row in set (1.12 sec)这个时候查看执行计划,就会看到derived table的字样。
> explain select * from (select id from t_fund_info) t where t.id=138031; +----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 1998067 | Using where | | 2 | DERIVED | t_fund_info | index | NULL | account | 182 | NULL | 2127101 | Using index | +----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+ 2 rows in set (0.90 sec)看起来是1秒的执行速度,差别还不是很大,我们换第二种方式。
> select * from (select * from t_fund_info) t where t.id=138031; ERROR 126 (HY000): Incorrect key file for table '/tmp/#sql_3e34_0.MYI'; try to repair it 这个时候就会发现这么一个看似简单的查询竟然抛出了错误。