【发布时间】:2016-09-20 20:23:15
【问题描述】:
我是 Postgres 查询的新手。我正在尝试根据特定集从列的每个记录中提取子字符串。 假设,我从关键字“开始”和“结束”之间的每条记录中提取子串。所以问题是它可以在一条记录中多次出现“开始”和“结束”,并且需要提取每组“开始”和“结束”关键字之间发生的内容。
我们是否有可能通过 Postgres 中的单个查询来实现这一点,而不是创建一个过程?如果是,请您提供帮助或重定向我在哪里可以找到相关信息?
【问题讨论】:
我是 Postgres 查询的新手。我正在尝试根据特定集从列的每个记录中提取子字符串。 假设,我从关键字“开始”和“结束”之间的每条记录中提取子串。所以问题是它可以在一条记录中多次出现“开始”和“结束”,并且需要提取每组“开始”和“结束”关键字之间发生的内容。
我们是否有可能通过 Postgres 中的单个查询来实现这一点,而不是创建一个过程?如果是,请您提供帮助或重定向我在哪里可以找到相关信息?
【问题讨论】:
假设/总是分隔元素,你可以使用string_to_array()将字符串转换为多个元素,使用unnest()将数组转换为结果。然后您可以使用regexp_replace() 去掉花括号中的分隔符:
select d.id, regexp_replace(t.name, '{start}|{end}', '', 'g')
from the_able d
cross join unnest(string_to_array(d.body,'/')) as t(name);
SQLFiddle 示例:http://sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/8863
【讨论】:
您可以使用正则表达式和 PostgreSQL 正则表达式函数 regexp_matches(匹配标签之间的内容)和 regexp_replace(删除标签)来实现这一切:
with t(id,body) as (values
(1, '{start}John{end}/{start}Jack{end}'),
(2, '{start}David{end}'),
(3, '{start}Ken{end}/{start}Kane{end}/{start}John{end}'))
select id, regexp_replace(
(regexp_matches(body, '{start}.*?{end}', 'g'))[1],
'^{start}|{end}$', '', 'g') matches
from t
【讨论】: