关于postgresql:在根据其他列中的值解析列值时需要帮助

Need help in parsing column value based on value in other column

我有两列,COL1 和 COL2。 COL1 的值类似于 'Birds sitting on $1 and enjoying',COL2 的值类似于 'the.location_value[/tree,\\building]'

我需要用 'Birds sitting on /tree and enjoying'

之类的值更新第三列 COL3

即第一列中的 $1 替换为 /tree

这是逗号分隔的单词列表中的第一个单词,在 COL2 中带有方括号 [],即 [/tree,\\building]

我想知道 postgresql 中最合适的字符串函数组合来实现这一点。


您需要首先从逗号分隔列表中提取第一个元素,为此,您可以使用 split_part() 但您首先需要提取实际的值列表。这可以使用带有正则表达式的 substring() 来完成:

1
SUBSTRING(col2 FROM '\\[(.*)\\]')

将返回 /tree,\\building

所以完整的查询是:

1
2
SELECT REPLACE(col1, '$1', split_part(SUBSTRING(col2 FROM '\\[(.*)\\]'), ',', 1))
FROM the_table;

在线示例:http://rextester.com/CMFZMP1728


这应该适用于 $:

之后的任何 (int) 数字

1
2
3
4
5
6
7
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,但您可以尝试使用关联子查询:

1
2
3
4
5
6
7
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