2011-02-11 59 views
0

我想寫一個詞彙數據庫來存儲由根和模式組成的詞,我想知道如何創建一個將結合根和模式的列,而忽略行沒有填充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函數來完成字符[]和文本字符串的合併嗎?我需要的一點正則表達式不應該很複雜,但我不知道如何將這個與查詢混合在一起,或者更好的是將它變成一個函數。

回答

1

我必須承認不喜歡在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 
+0

我原先存儲的根在形式`1-2-3`和所述陣列的一個字符串概念性更有意義;我還認爲這可能會使選擇單個字符更簡單。 – Robbie 2011-02-11 14:29:37

+0

我同意數組比字符串更好的存儲形式。可惜的是,Perl集成似乎沒有處理它(它接收數組的字符串表示形式作爲參數)。 – araqnid 2011-02-11 14:39:36

3
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;