PostgreSQL字符串替换
问题描述:
我想写一个词汇数据库来存储由根和模式组成的词,我想知道如何创建一个将结合根和模式的列,而忽略行没有填充SELECT
查询的两列。PostgreSQL字符串替换
基本上,我有一个从PostgreSQL数据库的输出:
SELECT root, root_i FROM tbl_roots NATURAL JOIN tbl_patterns NATURAL JOIN tbl_patterns_triliteral;
root | root_i
---------+--------
{s,ş,m} | 1u2u3a
{p,l,t} | 1u2u3a
{t,m,s} | 1u2u3a
{n,t,l} | 1u2u3a
{s,ş,m} | 1a2oi3
{p,l,t} | 1a2oi3
{t,m,s} | 1a2oi3
{n,t,l} | 1a2oi3
{s,ş,m} | 1o2i3
{p,l,t} | 1o2i3
{t,m,s} | 1o2i3
{n,t,l} | 1o2i3
{s,ş,m} | a12e3
{p,l,t} | a12e3
{t,m,s} | a12e3
{n,t,l} | a12e3
{s,ş,m} | 1u2á3
{p,l,t} | 1u2á3
{t,m,s} | 1u2á3
{n,t,l} | 1u2á3
{s,ş,m} |
{p,l,t} |
{t,m,s} |
{n,t,l} |
{s,ş,m} | 1e2é3
{p,l,t} | 1e2é3
{t,m,s} | 1e2é3
{n,t,l} | 1e2é3
{s,ş,m} |
{p,l,t} |
{t,m,s} |
{n,t,l} |
{s,ş,m} |
{p,l,t} |
{t,m,s} |
{n,t,l} |
{s,ş,m} |
{p,l,t} |
{t,m,s} |
{n,t,l} |
而且我想把它转换成上即时形成类似这样的:
root | root_i | word_i
---------+--------+--------
{s,ş,m} | 1u2u3a | suşuma
{p,l,t} | 1u2u3a | puluta
{t,m,s} | 1u2u3a | tumusa
{n,t,l} | 1u2u3a | nutula
{s,ş,m} | 1a2oi3 | saşoim
{p,l,t} | 1a2oi3 | paloit
{t,m,s} | 1a2oi3 | tamois
{n,t,l} | 1a2oi3 | natoil
{s,ş,m} | 1o2i3 | soşim
{p,l,t} | 1o2i3 | polit
{t,m,s} | 1o2i3 | tomis
{n,t,l} | 1o2i3 | notil
{s,ş,m} | a12e3 | asşem
{p,l,t} | a12e3 | aplet
{t,m,s} | a12e3 | atmes
{n,t,l} | a12e3 | antel
{s,ş,m} | 1u2á3 | suşám
{p,l,t} | 1u2á3 | pulát
{t,m,s} | 1u2á3 | tumás
{n,t,l} | 1u2á3 | nutál
{s,ş,m} | 1e2é3 | seşém
{p,l,t} | 1e2é3 | pelét
{t,m,s} | 1e2é3 | temés
{n,t,l} | 1e2é3 | neşél
凡word
列通过将root_i
列中的数字替换为root
列中该数字索引中的字符来动态生成。我还需要删除在两列中都没有条目的查询行,以减少输出中的混乱。
任何人都可以帮助我设计一个postgres函数来完成字符[]和文本字符串的合并吗?我需要的一点正则表达式不应该很复杂,但我不知道如何将这个与查询混合在一起,或者更好的是将它变成一个函数。
答
我必须承认不喜欢在sql/plpgsql函数中做很多字符串操作。 Perl有用于生成替换替换正则表达式匹配的运营商,这还算很好的工作:
create or replace function splice_to_word(root text, root_i text)
returns text strict immutable language plperl as $$
my $roots = shift;
my $template = shift;
$template =~ s{(\d+)}{substr($roots,$1-1,1)}ge;
return $template;
$$;
有一些污秽在PostgreSQL的数组似乎并没有被翻译成Perl的名单,所以我认为根源传递在作为字符串,例如:
select root, root_i, splice_to_word(array_to_string(root, ''), root_i) from data
答
select
root,
root_i,
translate(root_i, "123", array_to_string(root,'')) as word_i
NATURAL JOIN tbl_patterns
NATURAL JOIN tbl_patterns_triliteral
where root is not null and root_i is not null;
我原先存储的根在形式`1-2-3`和所述阵列的一个字符串概念性更有意义;我还认为这可能会使选择单个字符更简单。 – Robbie 2011-02-11 14:29:37
我同意数组比字符串更好的存储形式。可惜的是,Perl集成似乎没有处理它(它接收数组的字符串表示形式作为参数)。 – araqnid 2011-02-11 14:39:36