按條件刪除記錄時報You can’t specify target table for update in FROM clause錯誤解決方法(寫於20161107)
mysql中,不能先select一個表的記錄,在按此條件進行更新和刪除同一個表的記錄。解決辦法是,將select得到的結果,再通過中間表select一遍,這樣就規避了錯誤,這個問題只出現於mysql,mssql和oracle不會出現此問題。
自己例項一:
如下業務場景,ecs_order_shipping表裡面記錄了每一個訂單的配送流轉記錄,type從11,12,21,22,23這麼遞進,
按理說每個訂單的每一個type就出現一次,因為系統bug造成type為11、12的記錄,都出現了兩次或多次。對於每一個訂單,如果它有兩條type等於11的ecs_order_shipping記錄,那麼只保留第一條,其他的刪除。
一、先查出來那些要被刪除的記錄的id組合
#查出type為11的全部記錄
select * from ecs_order_shipping where type = 11;
#分組後,記錄少了,說明有重複的記錄
select * from ecs_order_shipping where type = 11 group by order_sn;
#這樣篩選出那些重複的訂單
select * from ecs_order_shipping where type = 11 group by order_sn having count(*) >1;
#從篩選的重複訂單中,得到id最大的
select max(id) from ecs_order_shipping where type=11 group by order_sn having count(*) >1;
二、根據這些id組合,刪除他們
delete from ecs_order_shipping where id in
(
select max(id) from ecs_order_shipping where type=11 group by order_sn having count(*) >1
)
這樣就會報錯!!!Error : You can't specify target table 'ecs_order_shipping' for update in FROM clause
三、如上,修改sql語句如下即可
/****每個訂單type等於11,12的記錄,出現了很多重複的,要刪除重複項,只留下最早的那個***/
delete from ecs_order_shipping where id in
(
select a.id from
(
select max(id) as id from ecs_order_shipping as b where b.type=11 group by b.order_sn HAVING count(*) >1
)as a
)
delete from ecs_order_shipping where id in
(
select a.id from
(
select max(id) as id from ecs_order_shipping as b where b.type=12 group by b.order_sn HAVING count(*) >1
)as a
)