需要帮助解析基于其他列中的值的列值

时间:2017-03-21 10:06:29

标签: postgresql postgresql-8.4

我有两列,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中最合适的字符串函数组合来实现这一点。

2 个答案:

答案 0 :(得分:2)

您需要首先从逗号分隔列表中提取第一个元素,为此,您可以使用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

答案 1 :(得分:0)

这个应该适用于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

更新:旧版本不支持LATERALWITH 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