mysql 出現 target table for update in FROM clause 錯誤的解決方法

mysql出現You can’t specify target table for update in FROM clause 這個錯誤的意思是不能在同一個sql語句中,先select同一個表的某些值,然後再update這個表。


例如:message表保存了多個用戶的消息

創建表

CREATE TABLE `message` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `uid` int(10) unsigned NOT NULL,
 `content` varchar(255) NOT NULL,
 `addtime` datetime NOT NULL,
 PRIMARY KEY (`id`),
 KEY `uid` (`uid`),
 KEY `addtime` (`addtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 

insert into message(uid,content,addtime) values
(1,'content1','2016-09-26 00:00:01'),
(2,'content2','2016-09-26 00:00:02'),
(3,'content3','2016-09-26 00:00:03'),
(1,'content4','2016-09-26 00:00:04'),
(3,'content5','2016-09-26 00:00:05'),
(2,'content6','2016-09-26 00:00:06'),
(2,'content7','2016-09-26 00:00:07'),
(4,'content8','2016-09-26 00:00:08'),
(4,'content9','2016-09-26 00:00:09'),
(1,'content10','2016-09-26 00:00:10');

表結構及數據如下:

mysql> select * from message;
+----+-----+-----------+---------------------+
| id | uid | content   | addtime             |
+----+-----+-----------+---------------------+
|  1 |   1 | content1  | 2016-09-26 00:00:01 |
|  2 |   2 | content2  | 2016-09-26 00:00:02 |
|  3 |   3 | content3  | 2016-09-26 00:00:03 |
|  4 |   1 | content4  | 2016-09-26 00:00:04 |
|  5 |   3 | content5  | 2016-09-26 00:00:05 |
|  6 |   2 | content6  | 2016-09-26 00:00:06 |
|  7 |   2 | content7  | 2016-09-26 00:00:07 |
|  8 |   4 | content8  | 2016-09-26 00:00:08 |
|  9 |   4 | content9  | 2016-09-26 00:00:09 |
| 10 |   1 | content10 | 2016-09-26 00:00:10 |
+----+-----+-----------+---------------------+
10 rows in set (0.00 sec)

然後執行將每個用戶第一條消息的內容更新爲Hello World

mysql> update message set content='Hello World' where id in(select min(id) from message group by uid);
ERROR 1093 (HY000): You can't specify target table 'message' for update in FROM clause
1
2
因爲在同一個sql語句中,先select出message表中每個用戶消息的最小id值,然後再更新message表,因此會出現 ERROR 1093 (HY000): You can’t specify target table ‘message’ for update in FROM clause 這個錯誤。


解決方法:select的結果再通過一箇中間表select多一次,就可以避免這個錯誤

update message set content='Hello World' where id in( select min_id from ( select min(id) as min_id from message group by uid) as a );
1
執行:

mysql> update message set content='Hello World' where id in( select min_id from ( select min(id) as min_id from message group by uid) as a );
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> select * from message;
+----+-----+-------------+---------------------+
| id | uid | content     | addtime             |
+----+-----+-------------+---------------------+
|  1 |   1 | Hello World | 2016-09-26 00:00:01 |
|  2 |   2 | Hello World | 2016-09-26 00:00:02 |
|  3 |   3 | Hello World | 2016-09-26 00:00:03 |
|  4 |   1 | content4    | 2016-09-26 00:00:04 |
|  5 |   3 | content5    | 2016-09-26 00:00:05 |
|  6 |   2 | content6    | 2016-09-26 00:00:06 |
|  7 |   2 | content7    | 2016-09-26 00:00:07 |
|  8 |   4 | Hello World | 2016-09-26 00:00:08 |
|  9 |   4 | content9    | 2016-09-26 00:00:09 |
| 10 |   1 | content10   | 2016-09-26 00:00:10 |
+----+-----+-------------+---------------------+
10 rows in set (0.00 sec)

注意,只有mysql會有這個問題,mssql與oracle都沒有這個問題。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章