Mysql里怎么只改字段里一部分数据,不用全替换那种方法分享
- 问答
- 2026-01-21 13:51:36
- 3
参考自 MySQL 官方文档关于字符串函数和 UPDATE 语句的章节,以及常见的数据库管理实践分享)
很多时候,我们确实会遇到只需要修改数据库表中某个字段里的一小部分内容,而不是把整个字段的值全部换掉的情况,产品经理说要把所有文章标题里的“APP”改成“应用”,但你肯定不能手动去一篇篇改,也不能直接用个 UPDATE 把标题全替换成“应用”两个字,那数据就全毁了,这时候,就需要用到一些精准的“手术刀”式操作。
核心的思路其实很简单,就是使用 MySQL 提供的字符串替换函数,再结合我们熟悉的 UPDATE 语句,来达到精准修改的目的,最常用、最直接的工具就是 REPLACE() 函数。
使用 REPLACE() 函数进行直接替换
REPLACE() 函数的作用就是在一个字符串里,找到指定的子字符串,然后把所有出现这个子字符串的地方都换成你指定的新字符串,它的语法是这样的:REPLACE(原始字符串, 要查找的旧字符串, 要替换成的新字符串)。
举个例子,假设我们有一张叫 articles 的表,里面有个 title 字段,现在需要把所有标题中的“APP”替换为“应用”。
那么我们的 SQL 语句就可以这么写:
UPDATE articles SET title = REPLACE(title, 'APP', '应用');
执行这条语句后,MySQL 会扫描 title 字段的每一个值。

- 是“这是一款好用的APP”,就会变成“这是一款好用的应用”。
- 原来是“APPStore”,就会变成“应用Store”。
- 如果某个标题里根本没有“APP”,微信小程序”,那么这个标题就不会有任何变化。
这种方法非常高效,一步到位,特别适合这种全局、统一的简单文本替换,但要注意,它是大小写敏感的,也就是说,‘APP’和‘app’会被认为是不同的字符串,如果你的数据里混用了大小写,可能需要配合其他函数先做处理,或者分别执行多次替换。
更精细的控制:使用 SUBSTRING()、CONCAT() 等函数组合
REPLACE() 函数是“全部替换”,但有时候我们的需求更刁钻一些,只想替换字段值中特定位置的字符,或者只想替换第一次或第二次出现的地方,而不是全部,这时候,就需要把几种字符串函数像搭积木一样组合起来用了。
常用的“积木块”有:
SUBSTRING(字符串, 开始位置, 长度):从字符串的指定位置开始,截取指定长度的子串,注意,MySQL中字符串的起始位置是1,不是0。LOCATE(要查找的子串, 字符串, 开始查找的位置):返回子串在字符串中第一次出现的位置,如果没找到,返回0。LEFT(字符串, 长度):从字符串左边开始截取指定长度的子串。RIGHT(字符串, 长度):从字符串右边开始截取指定长度的子串。CONCAT(字符串1, 字符串2, ...):把多个字符串连接成一个字符串。
只替换第一次出现的文本
假设我们还是想把“APP”改成“应用”,但每个标题里只改第一次出现的,后面的不动,这该怎么做呢?

思路是:找到“APP”第一次出现的位置,然后把标题分成三部分:APP前面的部分 + 应用 + APP后面的部分,再用 CONCAT 把它们拼起来。
SQL 可能会稍微复杂一点:
UPDATE articles= CONCAT(
LEFT(title, LOCATE('APP', title) - 1), -- 第一部分:从开头到'APP'之前
'应用', -- 第二部分:新的替换文本
SUBSTRING(title, LOCATE('APP', title) + LENGTH('APP')) -- 第三部分:从'APP'之后到结尾
)
WHERE LOCATE('APP', title) > 0; -- 只处理那些包含'APP'的记录
我们来分解一下:
LOCATE('APP', title)找到了‘APP’在 title 中第一次出现的位置,比如在第5个字符。LEFT(title, 位置 - 1)就截取了前4个字符。SUBSTRING(title, 位置 + LENGTH('APP'))就是从第5+3=8个字符开始,一直截取到末尾。- 最后用
CONCAT把“前4个字符” + “应用” + “第8个字符之后的所有字符”拼接到一起。 - 最后的
WHERE条件很重要,确保只修改那些确实包含‘APP’的记录,提高效率。
修改特定位置的字符
我们有一个 phone_number 字段,存储的是“13812345678”,现在想把它中间四位用星号隐藏,变成“138****5678”。
思路就是截取头三位、中间四位替换成星号、尾四位,然后拼接。

UPDATE users
SET phone_number = CONCAT(
LEFT(phone_number, 3), -- 前三位,#39;138'
'****', -- 替换的四个星号
RIGHT(phone_number, 4) -- 后四位,#39;5678'
);
使用 CASE WHEN 进行条件判断
我们是否修改一个字段,还需要根据这个字段当前的值来决定,我们想给所有 status 字段为‘pending’的记录,在其 note 备注前面加上“【待处理】”字样,而其他状态的记录不动。
这时,CASE WHEN 语句就派上用场了。
UPDATE orders
SET note = CASE
WHEN status = 'pending' THEN CONCAT('【待处理】', note)
ELSE note -- 其他情况,保持原样不变
END;
这条语句会检查每一条记录的 status,如果是‘pending’,就执行 CONCAT 拼接新内容;如果不是,就把 note 设置成它本身(相当于没变),这样就实现了有条件的部分修改。
非常重要的安全提醒
在进行任何 UPDATE 操作,尤其是这种部分修改之前,一定要先备份数据!最起码,要先执行一个 SELECT 语句,用你打算在 UPDATE 里使用的逻辑,预览一下修改后的结果是什么样的,确认无误后再执行更新。
对于上面那个复杂的只替换第一次‘APP’的例子,你应该先这样检查:
SELECTAS 原标题,
CONCAT( LEFT(title, LOCATE('APP', title) - 1), '应用', SUBSTRING(title, LOCATE('APP', title) + LENGTH('APP'))) AS 新标题
FROM articles
WHERE LOCATE('APP', title) > 0;
仔细核对“原标题”和“新标题”两列,确认修改效果完全符合你的预期之后,再把 SELECT ... FROM ... 换成 UPDATE ... SET ... = ... FROM ... 来执行真正的更新操作,这一步是防止误操作导致数据丢失的黄金法则。
MySQL 里只修改字段的一部分数据,主要依靠字符串函数。REPLACE() 解决大部分简单全局替换,而 SUBSTRING, LOCATE, CONCAT 等函数的组合可以应对更复杂的、需要精确定位的修改需求。CASE WHEN 则用于需要根据条件判断是否修改的场景,无论用哪种方法,操作前备份和预览都是必须的。
本文由雪和泽于2026-01-21发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/84005.html
