在PostgreSQL中提取,匹配和组合字符串中的信息到数组中

时间:2016-10-06 14:18:02

标签: sql postgresql

问题

抱歉,有问题,把它分成小块):

我有以下一个列表A

                    s                            
-------------------------------------------
 (AAB) Some name1 1234 (XY*) Hello world 12
 (BB) Just one 123

和查找表L

 a1  | a2  
-----+-----
 XY* | XY
 AAB | A2B

我想:

  1. 检索括号中的部分:(AAB, XY*)
  2. 从查找表中获取相应的a2条目:(A2B, XY)
  3. 检索条目的数字部分:(1234, 12)
  4. 将2和4的结果合并到一个数组中:(A2B1234, XY12)
  5. 结果将是

                        s                            
    -------------------------------------------
     {A2B1234, XY12}
     {BB123}
    

    我尝试了什么

    这是我走了多远:

    • 1:

      SELECT array_to_string(regexp_matches(s, '\((.*?)\)', 'g'), '') as in_bracket FROM A;

    • 3:

      SELECT array_to_string(regexp_matches(s, '(\d+)', 'g'), '') as numbers FROM A;

    斗争开始了。我怎么能

    1. 将值(in_bracket)替换为动态查找值?
    2. 将两个select子句的结果合并为每行一个数组?
    3. 数据:

      CREATE TABLE A (
        s VARCHAR
      );
      INSERT INTO a VALUES
        ('(AAB) Some name1 1234 (BB) More text 99 (XY*) Hello world 12'),
        ('(BB) Just one 123');
      
      CREATE TABLE L (
        a1 VARCHAR(4),
        a2 VARCHAR(4)
      );
      INSERT INTO L VALUES 
        ('XY*', 'XY'),
        ('AAB', 'A2B');
      

1 个答案:

答案 0 :(得分:1)

我来到这种形式:

WITH parts AS (
    SELECT
        id,
        (regexp_matches(s, '\(([^\)]+)\)[^0-9]*([0-9]+)', 'g'))[1] AS search,
        (regexp_matches(s, '\(([^\)]+)\)[^0-9]*([0-9]+)', 'g'))[2] AS number
    FROM
        A
)
SELECT
    array_agg(L.a2 || parts.number)
FROM
    parts
    JOIN L
    ON (L.a1 = parts.search)
GROUP BY
    parts.id;

输出结果为:

{A2B1,XY12}
{BB123}

有一些事情需要澄清:

  • 究竟是什么“条目的数字部分” - 在给定的示例中有“name1”,所以我的正则表达式匹配“1” - 请注意A2B1返回而不是A2B1234
  • L中的
  • 没有BB的条目 - 我已将其手动添加到我的测试L表中 - 在这种情况下是否应该使用括号中的文字?
  • 我需要对表A中的结果进行分组,我假设有id列 - 如果它是quniue,您也可以使用s

您可能需要调整我使用过的正则表达式。以下是对我的版本的解释:

\(         - '('
([^\)]+)   - match of sequence of any char except ')' - this will be for example `AAB` or `XY*`
\)         - ')'
[^0-9]*    - any sequence of chars except digits (no-matching group)
([0-9]+)   - match of non-empty sequence of digits