You can't specify target table 'a' for update in FROM clause

項目中有一個功能變更上線,其中有一張表ttt的字段cc,歷史數據須要處理,把字段cc中爲’xxx’的值替換爲'yyy'。html

表A結構以下:sql

CREATE TABLE `ttt` (
  `id` bigint NOT NULL,
  `aa` int NOT NULL COMMENT 'xxx',
  `bb` int(11) NOT NULL COMMENT 'xxx',
  `cc` varchar(64) NOT NULL COMMENT 'xxx',
  ...
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_aa_bb_cc` (`aa`,`bb`,`cc`) USING BTREE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8

更新sql以下:code

UPDATE ttt SET cc='yyy' WHERE cc='xxx';

執行報錯:
Duplicate entry 'xx-xx-yyy' for key 'uk_aa_bb_cc'htm

由於相同的aa、bb下可能已經有cc值爲'yyy'的數據了,
好比已有歷史數據:
aa bb cc
1 1 xxx
1 1 yyy
這個時候執行更新sql,就會有2條1 1 yyy,因爲字段aa、bb、cc因業務屬性設置爲惟一索引,因此更新失敗。blog

修改更新sql,將有相同yyy的數據排除掉:索引

UPDATE ttt a SET a.cc='yyy' WHERE a.cc='xxx' 
AND NOT EXISTS (SELECT 1 FROM ttt b WHERE a.aa=b.aa AND a.bb=b.bb AND b.cc='yyy');

執行報錯:
You can't specify target table 'a' for update in FROM clauseci

改爲IN條件:get

UPDATE ttt a SET a.cc='yyy' WHERE a.cc='xxx' 
AND NOT IN (SELECT id FROM ttt b WHERE a.aa=b.aa AND a.bb=b.bb AND b.cc='yyy');

也報一樣的錯。table

這個錯誤在MySQL會出現,在SQLServer、Oracle上沒有,意思是:
不能先select出同一表中的某些值,再update這個表(在同一語句中),即不能依據某字段值作判斷再來更新某字段的值。date

修改sql以下:

UPDATE ttt a SET a.cc='yyy' WHERE a.cc='xxx' 
AND a.id NOT IN (
SELECT id FROM(SELECT id FROM ttt b WHERE a.aa=b.aa AND a.bb=b.bb AND b.cc='yyy')c
);

執行仍是報錯:
Unknown column 'a.aa' in 'where clause'

看來直接嵌套一層查詢也不行。
再次修改sql,使用UPDATE JOIN語法:

UPDATE ttt a
LEFT JOIN ttt b ON a.aa=b.aa AND a.bb=b.bb AND b.cc='yyy'
SET a.cc='yyy'
WHERE a.cc='xxx' AND b.id IS NULL

由於須要排除掉相同記錄,這裏用LEFT JOIN而且條件爲IS NULL的方式
再次執行sql成功。

在執行sql先後能夠用sql進行數據查詢,好比:
查詢沒有相同aa、bb且ccc僅有'xxx'的數據(即預先驗證上面的更新sql影響的數據狀況):

SELECT * 
FROM ttt a
LEFT JOIN ttt b ON a.aa=b.aa AND a.bb=b.bb AND b.cc='yyy'
WHERE a.cc='xxx' AND b.id IS NULL

查詢有相同aa、bb且cc存在xxx、yyy值的數據:

SELECT aa,bb,COUNT(*) FROM ttt
WHERE cc IN('xxx','yyy')
GROUP BY aa,bb
HAVING COUNT(*)>1

經過aa、bb條件查詢:

SELECT * FROM ttt WHERE aa='xx' AND bb='yy';

參考:
MySQL 中 You can't specify target table '表名' for update in FROM clause錯誤解決辦法
MySQL update join語句

相關文章
相關標籤/搜索