>我有两列,COL1 和 COL2。COL1 具有类似'Birds sitting on $1 and enjoying'
的值,COL2 具有类似'the.location_value[/tree,building]'
我需要用类似 'Birds sitting on /tree and enjoying'
的值更新第三列 COL3
即 第 1 列中的$1
替换为 /tree
这是COL2中带有方括号[]的逗号分隔单词列表中的第一个单词,即 [/tree,building]
我想知道 postgresql 中字符串函数的最佳合适组合来实现这一目标。
您需要首先从逗号分隔的列表中提取第一个元素,为此,您可以使用split_part()
但首先需要提取实际的值列表。这可以使用带有正则表达式的substring()
来完成:
substring(col2 from '[(.*)]')
将返回/tree,building
因此,完整的查询将是:
select replace(col1, '$1', split_part(substring(col2 from '[(.*)]'), ',', 1))
from the_table;
在线示例:http://rextester.com/CMFZMP1728
这个应该适用于$
之后的任何(int
(数字:
select t.*, c.col3
from t,
lateral (select string_agg(case
when o = 1 then s
else (string_to_array((select regexp_matches(t.col2, '[(.*)]'))[1], ','))[(select regexp_matches(s, '^$(d+)'))[1]::int] || substring(s from '^$d+(.*)')
end, '' order by o) col3
from regexp_split_to_table(t.col1, '(?=$d+)') with ordinality s(s, o)) c
http://rextester.com/OKZAG54145
注意:虽然这不是最有效的。它每次拆分col2
的值(在方括号中(以替换$N
。
更新:旧版本不支持LATERAL
和WITH ORDINALITY
,但您可以尝试使用关联的子查询:
select t.*, (select array_to_string(array_agg(case
when s ~ E'^\$(\d+)'
then (string_to_array((select regexp_matches(t.col2, E'\[(.*)\]'))[1], ','))[(select regexp_matches(s, E'^\$(\d+)'))[1]::int] || substring(s from E'^\$\d+(.*)')
else s
end), '') col3
from regexp_split_to_table(t.col1, E'(?=\$\d+)') s) col3
from t