【问题标题】:PostgreSQL string character replacementPostgreSQL 字符串字符替换
【发布时间】:2011-02-11 08:36:09
【问题描述】:

我正在尝试编写一个词汇数据库来存储由词根和模式组成的单词,我想知道如何为我创建一个将词根和模式结合起来的列,同时忽略没有两者的行SELECT 查询的列已填充。

基本上,我有来自 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函数来合并字符[]和文本字符串?我需要的一点正则表达式不应该很复杂,但我不知道如何将它与查询混合,或者更好的是,将它变成一个函数。

【问题讨论】:

    标签: database regex postgresql


    【解决方案1】:
    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;
    

    【讨论】:

    • 酷。在这里我认为它需要正则表达式。稍作微调,效果很好,没有用户定义函数调用的开销。
    【解决方案2】:

    我必须承认我不喜欢在 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
    

    【讨论】:

    • 我最初将根存储在1-2-3 形式的字符串中,并且该数组在概念上更有意义;我还认为这可能会使选择单个字符更简单。
    • 我同意数组是比字符串更好的存储形式。遗憾的是 Perl 集成似乎没有处理它(它接收数组的字符串表示形式作为参数)。
    • 嘿,它有效!我不得不将\d+ 更改为\d,因为需要维护序列,但这是一个开始。
    • 啊,好点子。我假设您的数据意味着根数组中的元素永远不会超过 10 个。
    • 是的,root 的长度在两到五个字符之间,但到目前为止我只写了两到三个字符的表格。一旦我完成了这一切并开始工作,如果我需要,插入一个额外的表格会相对简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多