项目中有一个功能变动上线,其中有一张表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. Bootstrap+Hbuilder

    出处:http://blog.csdn.net/antony9118/article/details/52189525 1 BootStrap的优点 BootStrap是现在最受欢迎的前端框架,对cs ...

  2. 快速认识Python

    1.数字和表达式 什么是表达式,1+2*3 就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数.1+2*3 经过计算后得到的结果是7,就1+2*3 = 7.我们可以将计算结果保存在一个变 ...

  3. 用js刷剑指offer(数值的整数次方)

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 保证base和exponent不同时为0 牛客网链接 思路 快速幂算法,举个例 ...

  4. jade安全转义和非转义

      - var data = 'text' - var htmlData = ')</script><span>script</span>' 例如上面的例子,假如没 ...

  5. 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...

  6. P1004 方格取数[棋盘dp]

    题目来源:洛谷 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 ...

  7. Hibernate初探之单表映射——使用Junit进行测试

    编写一个Hibernate例子 第四步:使用Junit进行测试 三个常用的注解标签 @Test:测试方法 @Before:初始化方法 @After:释放资源 执行顺序:Before注解标签下的方法  ...

  8. VisualGC,JVMStat安装配置

    通过VisualGC工具可以通过图形化方式查看JVM垃圾收集的情况. http://www.oracle.com/technetwork/java/jvmstat-142257.html 下载 htt ...

  9. linux 优化

    如何优化Linux系统? 1)不用root超级用户登录,添加普通用户,通过sudo授权管理:/etc/sudoers 2)更改默认的远程连接ssh服务端口号,禁止root用户远程登录到服务器:/etc ...

  10. jaxb读有BOM的XML文件问题

    一开始找了半天没找到什么原因,读文件就报错: Content is not allowed in prolog 后来发现是文件是UTF-8带BOM和不带BOM的问题 问题就好解决了,直接读带BOM文件 ...