本文共 2077 字,大约阅读时间需要 6 分钟。
小引
大千世界无奇不有,不怕做不到就怕想不到。在MySQL软件开发过程中,有时就需要把一个表中的两列数据进行交换。例如,我最近遇到的一个案例是项目数据准备时客户把表格中两列数据弄反了(把A列数据输入到了B列,把B列数据输入到了A列),真让人苦笑不得。解决的最好办法自然是直接修改系统数据库对应表中数据----如果通过前台界面修改则麻烦大了!其实,细想来,实践中很可能也存在要求根据情况交换表格中两列数据的案例。废话不说了,看正文。
解决方案
使用update命令,这完全得益于MySQL SQL命令功能的强大支持。
表格中原来数据类似如下:
select * from product; +----+--------+----------------+--------+| id | name | original_price | price | +----+--------+----------------+--------+| 1 | 雪糕 | 5.00 | 3.50 | | 2 | 鲜花 | 18.00 | 15.00 | | 3 | 甜点 | 25.00 | 12.50 | | 4 | 玩具 | 55.00 | 45.00 || 5 | 钱包 | 285.00 | 195.00 |
现在要求互换original_price与price的值,使用如下方法:
update product as a, product as b set a.original_price=b.price, a.price=b.original_price where a.id=b.id;
验证一下:
select * from product; +----+--------+----------------+--------+| id | name | original_price | price | +----+--------+----------------+--------+| 1 | 雪糕 | 3.50 | 5.00 | | 2 | 鲜花 | 15.00 | 18.00 | | 3 | 甜点 | 12.50 | 25.00 | | 4 | 玩具 | 45.00 | 55.00 || 5 | 钱包 | 195.00 | 285.00 |
扩展问题
上面直接使用update交换一个表中两列(自然是同一数据类型)的例子有一个特殊情况,其实也正是我要解决的真正问题。具体地说,我们的用户在初期准备的部分数据中对于表中的两列数据弄反了。但是,对于以后输入的数据却没有弄反。这种情况下,我们需要找出前面弄反的记录范围,然后针对这部分记录实施上面的操作。但遗憾的是,MySQL中的update语句是不支持limit子句的。官方正规的描述如下:
For the multiple-table syntax, UPDATE updates rows in each table named in table_references that satisfy the conditions. Each matching row is updated once, even if it matches the onditions multiple times. For multiple-table syntax, ORDER BY and LIMIT cannot be used.
我试验了一下,的确如此。
无奈我们只能使用变通的办法。其中一个方法是,先把上面指定范围的记录选择出来并生成到一个临时表中,然后针对原表和这个临时表使用update语句实现交换上面范围记录中各个对应字段值的目的。
但这里有一个小插曲是:MySQL不直接支持类似于MS SQL Server的select into newtable这样的语句。不过,我们可以使用变通的其他语句实现,如下:
Create table tmp(Select * from mv_person2 limit 0,10);
上面语句的含义是,生成一个新表tmp,该表中的字段及值是另一个表mv_person2中从第1到第10条记录数据。这样便实现了上面生成一个临时表之目的。
有了上面的临时表tmp,再使用update语句实现交换表格mv_person2中指定范围(例如从第1到第10条记录数据)两列便轻松了。答案如下:
update mv_person2 as a, tmp as b set a.original_price=b.price, a.price=b.original_price where a.id=b.id;
从而间接实现了交换一个表中某指定范围内两列数据值之目的。
参考
http://blog.csdn.net/fdipzone/article/details/50864196
https://www.2cto.com/database/201308/234769.html