在MySQL中,写SQL语句的时候 ,可能会遇到You can't specify target table '表名' for update in FROM clause这样的错误,它的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中)。


1、问题是如何出现的?


数据准备

CREATE TABLE T_Person(
	pId INT PRIMARY KEY AUTO_INCREMENT,
	pName VARCHAR(20)
);

INSERT INTO T_Person(pName) VALUES('陈一');
INSERT INTO T_Person(pName) VALUES('黄二');
INSERT INTO T_Person(pName) VALUES('张三');
INSERT INTO T_Person(pName) VALUES('张三');
INSERT INTO T_Person(pName) VALUES('李四');
INSERT INTO T_Person(pName) VALUES('李四');
INSERT INTO T_Person(pName) VALUES('王五');
INSERT INTO T_Person(pName) VALUES('赵六');
INSERT INTO T_Person(pName) VALUES('赵六');
INSERT INTO T_Person(pName) VALUES('钱七');
INSERT INTO T_Person(pName) VALUES('王五');
INSERT INTO T_Person(pName) VALUES('李四');
INSERT INTO T_Person(pName) VALUES('孙八');
INSERT INTO T_Person(pName) VALUES('杨九');
INSERT INTO T_Person(pName) VALUES('张三');
INSERT INTO T_Person(pName) VALUES('吴十');

SELECT * FROM T_Person;


数据如下:

MySQL问题:You can't specify target table '表名' for update in FROM clause_mysql


通过看表中的数据,我们可以知道里面包含重复的数据:如“张三”、“李四”等。


那究竟有哪些名字出现重复了呢?

SELECT pName FROM T_Person GROUP BY pName HAVING COUNT(pName)>1;

MySQL问题:You can't specify target table '表名' for update in FROM clause_MySQL_02

接下来,我们把凡是有重复名字的记录全部删除

DELETE FROM T_Person
WHERE pName IN (SELECT pName 
		FROM T_Person 
		GROUP BY pName HAVING COUNT(pName)>1);

这时候,我们会遇到一个错误:

错误码: 1093
You can't specify target table 'T_Person' for update in FROM clause


2、问题如何解决

将SELECT出的结果再通过中间表SELECT一遍,这样就规避了错误。

例如:

DELETE FROM T_Person
WHERE pName IN (SELECT pName 
		FROM (SELECT pName 
		      FROM T_Person 
		      GROUP BY pName HAVING COUNT(pName)>1
		) AS temp);

再用查看数据

SELECT * FROM T_Person;

结果如下:

MySQL问题:You can't specify target table '表名' for update in FROM clause_MySQL_03


注意,这个问题只出现于MySQL,MSSQL和Oracle不会出现此问题。