在开发过程中,有时由于业务等需要把一个表中的两列数据进行交换。
解决方案
使用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;
从而间接实现了交换一个表中某指定范围内两列数据值之目的。