在更新中使用replace()函数来更改一列的多个子字符串

问题描述 投票:0回答:3

假设我有

student
表,其中有一列
name

name
列的值为“studenttone”、“studenttwo”、“student Three”
& 我想用“student1”、“student2”、“student3”替换它们。

对于单个更换来说非常简单:

update student set name = replace(name, 'one', '1')

但是多次替换呢?有什么想法吗?

sql postgresql sql-update pattern-matching
3个回答
7
投票

我只会使用多个更新语句,但如果您绝对必须在一个语句中执行此操作,只需嵌套替换调用即可:

update student set
  name = replace(replace(replace(name, 'one', '1'), 'two', '2'), 'three', '3')

这是有效的,因为(尽管效率低下)如果未找到搜索词,则对

replace()
的调用无效。


4
投票

REPLACE

虽然您可以将所有内容打包到一个语句中,但如果没有匹配的

WHERE
条件来排除未受影响的行,效率会很低。

UPDATE student SET name = replace(name, 'one', '1') WHERE name LIKE '%one';
UPDATE student SET name = replace(name, 'two', '2') WHERE name LIKE '%two';
UPDATE student SET name = replace(name, 'three', '3') WHERE name LIKE '%three';

这只查找并更新实际更改的行。根据您的示例匹配字符串的末尾。
最有效的方法是将其与类似 @Bohemian 建议的东西结合起来: UPDATE student SET name = replace(replace(replace( name , 'one' , '1') , 'two' , '2') , 'three', '3') WHERE name ~ '(one|two|three)$';

但要确保一个替换不会影响下一个。

实际上,几个 OR 运算的

LIKE

表达式通常比单个

正则表达式
更快,所以: WHERE (name LIKE '%one' OR name LIKE '%two' OR name LIKE '%three');

CASE

另一种可能性(在下面的评论中建议):

SET name = CASE WHEN name LIKE '%one' THEN replace(name, 'one', '1') WHEN name LIKE '%two' THEN replace(name, 'two', '2') WHEN name LIKE '%three' THEN replace(name, 'three', '3') ELSE name END

根据
具体

情况,这可能会被优化。举个例子: SET name = CASE right(name, -7) WHEN 'one' THEN student || '1' WHEN 'two' THEN student || '2' WHEN 'three' THEN student || '3' ELSE name END

ELSE name

子句对于返回尚未被替换的原始值(如果有)非常重要。如果省略

ELSE
子句,您将得到
NULL
而不是尚未替换的原始值。
    


0
投票

select multi_replace('foo and bar is not foobar', '{"bar":"foo", "foo":"bar", "foobar":"foobar"}'::jsonb);

https://wiki.postgresql.org/wiki/Multi_Replace_plpgsql

© www.soinside.com 2019 - 2024. All rights reserved.