【问题标题】:Extracting number of specific length from a string in Postgres从 Postgres 中的字符串中提取特定长度的数量
【发布时间】:2019-07-24 07:34:33
【问题描述】:

我正在尝试从像

这样的 cmets 中提取一组数字
"on april-17 transactions numbers are 12345 / 56789"
"on april-18 transactions numbers are 56789"
"on may-19 no transactions"

它们存储在表 cmets 中名为“com”的列中

我的要求是获得特定长度的数字。本例中长度为 5,所以 12345 和 56789 分别来自上述字符串,可能有 0 个五位数字或超过 2 个五位数字。

我尝试使用 regexp_replace 得到以下结果,我正在尝试找到一个有效的正则表达式或其他方法来实现它

select regexp_replace(com, '[^0-9]',' ', 'g') from comments;

                      regexp_replace                   
----------------------------------------------------
          17                          12345   56789

我希望结果只会得到 ​​p>

column1 | column2
12345     56789

【问题讨论】:

  • 是否总是有 2 个并且只有 2 个数字是匹配的情况?或者,可能只有 1 个或 3 个五位数字吗?
  • 是的,可以有更多,0 个五位数字或超过 2 个五位数字
  • 问题是您不能以简单的方式创建动态列数。你需要知道你会得到多少列。
  • 那么如果我们限制为两个,我们如何实现呢?
  • 给出了精确两列的解决方案。一次尝试获得一列,第二次获得两列是不可能的。如果我们将其限制为两个,即使您只找到一个数字,也会始终显示两列。在这种情况下,第二个将是 NULL。这是可能的

标签: sql postgresql regex-recursion


【解决方案1】:

没有简单的方法来创建获取任意数量列的查询:它不能为一个数字创建一列,并且在下一次尝试时查询会给出两个。


对于固定的两列:

demo:db<>fiddle

SELECT 
   matches[1] AS col1,
   matches[2] AS col2
FROM ( 
    SELECT
        array_agg(regexp_matches[1]) AS matches
    FROM
        regexp_matches(
            'on april-17 transactions numbers are 12345 / 56789', 
            '\d{5}',
            'g'
        )
) s
  1. regexp_matches() 在每次发现的一行中给出所有发现
  2. array_agg() 将所有元素放入一个数组中
  3. 数组元素可以作为单独的列给出。

【讨论】:

  • 如果这些输入 cmets 来自表列,则上述 SQL 语句不会产生所有值
  • @Maverick 您当然应该调整您的查询。 dbfiddle.uk/… ...这个包含没有任何数字的元素:dbfiddle.uk/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多