项目中有一个功能变动上线,其中有一张表ttt的字段cc,历史数据需要处理,把字段cc中为’xxx’的值替换为'yyy'。

表A结构如下:

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如下:

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

执行报错:

Duplicate entry 'xx-xx-yyy' for key 'uk_aa_bb_cc'

因为相同的aa、bb下可能已经有cc值为'yyy'的数据了,

比如已有历史数据:

aa bb cc

1 1 xxx

1 1 yyy

这个时候执行更新sql,就会有2条1 1 yyy,由于字段aa、bb、cc因业务属性设置为唯一索引,所以更新失败。

修改更新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 clause

改成IN条件:

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');

也报同样的错。

这个错误在MySQL会出现,在SQLServer、Oracle上没有,意思是:

不能先select出同一表中的某些值,再update这个表(在同一语句中),即不能依据某字段值做判断再来更新某字段的值。

修改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语句

You can't specify target table 'a' for update in FROM clause的更多相关文章

  1. mysql中更新或者删除语句中子语句不能操作同一个表You can't specify target table 'test' for update in FROM clause

    问题描述:有个数据表test,有个字段value,如下 mysql> select * from test;+----+------------------------------------+ ...

  2. mysql的一个特殊问题 you can't specify target table 'cpn_regist' for update in FROM clause

    今天在操作数据库的时候遇到了一个问题,sql语句如下: UPDATE cpn_yogurt_registration SET dep1Name = '1' WHERE `key` in  (SELEC ...

  3. Mysql update in报错 [Err] 1093 - You can't specify target table 'company_info' for update in FROM clause

    Mysql update in报错 解决方案: [Err] 1093 - You can't specify target table 'company_info' for update in FRO ...

  4. 错误:You can't specify target table 'xxx' for update in FROM clause的解决

    问题: 今天在MySQL数据库删除重复数据的时候遇到了一个问题.如下脚本: DELETE FROM tempA WHERE tid IN ( SELECT MAX(tid) AS tid FROM t ...

  5. [Err] 1093 - You can't specify target table 's' for update in FROM clause

    [Err] 1093 - You can't specify target table 's' for update in FROM clause 执行SQL DELETE from book WHE ...

  6. 【MySQL】解决You can't specify target table 'user_cut_record_0413' for update in FROM clause

    问题 You can't specify target table 'user_cut_record_0413' for update in FROM clause 原因 待更新/删除的数据集与查询的 ...

  7. You can't specify target table 'ship_product_cat' for update in FROM clause

    有时候我们在编辑update时需要select作为条件,在mysql中有时会出现这样的错误:You can't specify target table for update in FROM clau ...

  8. MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause

    MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause 201 ...

  9. 关于mysql 5.7版本“报[Err] 1093 - You can't specify target table 'XXX' for update in FROM clause”错误的bug

    不同于oracle和sqlserver,mysql并不支持在更新某个表的数据时又查询了它,而查询的数据又做了更新的条件,因此我们需要使用如下的语句绕过: , notice_code ) a) ; 本地 ...

  10. MySQL - 1093异常 - You can't specify target table 't' for update in FROM clause

    有一个表示地区的表,表结构与数据大概如下表. ID NAME PARENT_ID 1 中国 2 广东省 1 3 广州市 2 4 荔湾区 3 5 越秀区 3 6 番禺区 3 7 小谷围街道 6 现为了查 ...

随机推荐

  1. Orion (system-on-a-chip)

      From Wikipedia: Orion is a system-on-a-chip manufactured by Marvell Technology Group and used in n ...

  2. c# 运算符和表达式

  3. ARP、Proxy ARP、Gratuitous ARP

    Proxy ARP 什么是Proxy ARP? 一个主机A(通常是路由器)有意应答另一个主机B的ARP请求(ARP requests).主机A通过伪装其身份,承担起将分组路由到真实目的地的责任.代理A ...

  4. SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)

    最近发现SSL/TLS漏洞已经修改过,但是绿盟扫描器还可以扫描出来,网上看了很多文章,但是能用的比较少,今天刚好有空,就自己写一下. 方法一: 控制面板--->系统和安全--->管理工具- ...

  5. Python查看模块函数,查看函数方法的详细信息

    Python查看方法的详情 1.通用的帮助函数help() 使用help()函数来查看函数的帮助信息. 如: import requests help(requests) 会有类似如下输出: 2.查询 ...

  6. 一:(1.1)了解MVC之路由重写

    Mvc默认路由 //系统的Url路由规则 routes.MapRoute( name: "Default", url: "{controller}/{action}/{i ...

  7. 三道习题(1、将单词表中由相同字母组成的单词归成一类,每类单词按照单词的首字母排序,并按 #每类中第一个单词字典序由大到小排列输出各个类别。 #输入格式:按字典序由小到大输入若干个单词,每个单词占一行,以end结束输入。)

    #coding=gbk ''' 1.将单词表中由相同字母组成的单词归成一类,每类单词按照单词的首字母排序,并按 #每类中第一个单词字典序由大到小排列输出各个类别. #输入格式:按字典序由小到大输入若干 ...

  8. Why do we name variables in Tensorflow?

    Reference:Stack Overflow. The name parameter is optional (you can create variables and constants wit ...

  9. c/c++编译器配置(交叉编译重要参数)、交叉编译动态库与as配置、mk初步

    gcc/g++/clang,相当于javac: 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数. clang: clang 是一个C.C++.Obj ...

  10. 【python】获取目录下的最新文件夹/文件

    直接上代码 def new_report(test_report): lists = os.listdir(test_report) #列出目录的下所有文件和文件夹保存到lists print(lis ...