You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中如何将name列拆分迁移为first_name和last_name列

问题根因

regexp_match(name, '[^\s]*')返回带{}的结果,是因为PostgreSQL中regexp_match的返回值是text[]文本数组类型,直接把数组赋值给文本类型字段,就会输出PostgreSQL数组默认的花括号包裹格式,不是你需要的纯字符串。

推荐实现:基础字符串函数方案(性能最高)

完全不需要用正则,用内置字符串定位、截取函数性能远高于正则,也100%匹配「第一个空白字符为分界」的规则,同时兼容name中无空白字符的边界场景(无空白时first_name取完整值,last_name为空):

UPDATE users
SET (first_name, last_name) = (
    TRIM(LEADING FROM SUBSTRING(name FOR STRPOS(name, ' '))),
    TRIM(LEADING FROM SUBSTRING(name FROM STRPOS(name, ' ') + 1))
);

注意:不要用split_part实现该逻辑,该函数仅能返回分隔后的指定序号分段,会丢失第一个空格后的多段内容,比如John Doe Jr会被拆成first_name=John、last_name=Doe,丢失Jr部分,不符合需求。
语句中加TRIM(LEADING ...)是为了兼容第一个空格前有连续多空白、name开头带空白的脏数据,如果你的数据格式完全规范,可以去掉trim逻辑。
测试name='John Doe Jr'场景时,执行后first_name='John',last_name='Doe Jr',完全符合拆分规则。

正则写法修复

如果一定要用正则实现,只需要取regexp_match返回数组的第一个元素即可,不要直接把数组赋值给字段:

UPDATE users
SET (first_name, last_name) = (
    (regexp_match(name, '^[^\s]+'))[1],
    TRIM(LEADING FROM regexp_replace(name, '^[^\s]+\s+', ''))
);

该写法效果和字符串函数方案一致,但正则匹配有额外性能开销,大批量数据迁移场景不推荐使用。

内容的提问来源于stack exchange,提问作者ussu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 11:48:28