sql子查詢更新表時(shí)加一層包裹為何奏效?
在mysql中,更新語句(如delete、INSERT、UPDATE)需要更新的表和子查詢中的FROM表不能相同。這導(dǎo)致了以下sql語句報(bào)錯(cuò):”delete FROM sys_post WHERE post_id NOT IN (select MIN(post_id) AS min_id FROM sys_post GROUP BY post_name);”。
然而,通過給子查詢加一層括號包裹,問題得以解決:”delete FROM sys_post WHERE post_id NOT IN (SELECT t.min_id FROM (SELECT MIN(post_id) AS min_id FROM sys_post GROUP BY post_name) t);”。
這一設(shè)計(jì)的緣由來自MySQL自身的機(jī)制限制,其他數(shù)據(jù)庫沒有這樣的約束。根據(jù)官方文檔,更新語句和子查詢FROM中的表不能指向同一張表。
為了繞開這一約束,MySQL提供了一個(gè)解決方法:創(chuàng)建一張中間表(衍生表)并為其指定一個(gè)別名,然后在子查詢中使用該別名。
在本例中,添加了一個(gè)中間表”t”,并指定其為子查詢派生表的結(jié)果。由于”t”與要更新的表”sys_post”不同,因此更新操作得以順利執(zhí)行。