PostgreSQL计数子字符串在文本中出现的次数

PostgreSQL计数子字符串在文本中出现的次数,sql,postgresql,Sql,Postgresql,我正在编写一个PostgreSQL函数来计算特定文本子字符串在另一段文本中出现的次数。例如,调用count('foobarbaz','ba')应该返回2 我理解,为了测试子字符串是否发生,我使用了类似于以下的条件: WHERE 'foobarbaz' like '%ba%' 但是,我需要它返回2表示“ba”出现的次数。我怎样才能继续 提前感谢您的帮助。使用正则表达式怎么样: SELECT count(*) FROM regexp_matches('foobarbaz', 'ba', '

我正在编写一个PostgreSQL函数来计算特定文本子字符串在另一段文本中出现的次数。例如,调用count('foobarbaz','ba')应该返回2

我理解,为了测试子字符串是否发生,我使用了类似于以下的条件:

    WHERE 'foobarbaz' like '%ba%'
但是,我需要它返回2表示“ba”出现的次数。我怎样才能继续


提前感谢您的帮助。

使用正则表达式怎么样:

SELECT count(*)
FROM regexp_matches('foobarbaz', 'ba', 'g');
'g'
标志在一个字符串上重复多个匹配项(不仅仅是第一个匹配项)。

有一个

str_count( src,  occurence )
基于

SELECT (length( str ) - length(replace( str, occurrence, '' ))) / length( occurence )

str_countm( src, regexp )
基于提到的@MikeT

SELECT count(*) FROM regexp_matches( str, regexp, 'g')
此处提供:

尝试:

SELECT array_length (string_to_array ('1524215121518546516323203210856879', '1'), 1) - 1

--RESULT: 7

我强烈建议查看我发布到的这个答案。结果表明,选择的答案比经过调整的
regexp\u replace()
版本要慢得多。创建行和运行聚合的开销实在太高了

最快的方法如下

SELECT
  (length(str) - length(replace(str, replacestr, '')) )::int
  / length(replacestr)
FROM ( VALUES
  ('foobarbaz', 'ba')
) AS t(str, replacestr);
我们到了

  • 取字符串的长度,
    L1
  • L1
    中减去已删除所有替换项的字符串长度
    L2
    ,得到
    L3
    字符串长度的差值
  • L3
    除以替换的长度以获得引用
  • 相比之下,使用
    regexp\u matches()
    的方法要快五倍

    SELECT count(*)
    FROM ( VALUES
      ('foobarbaz', 'ba')
    ) AS t(str, replacestr)
    CROSS JOIN LATERAL regexp_matches(str, replacestr, 'g');
    

    查看此问题的更新,以及此方法和最佳方法的比较。或者,我对DBA.SE.上另一个问题的答案。请查看我的答案,以获取更新的方法