PostgreSQL SQL查询以查找字符串中子字符串出现的次数

时间:2020-10-11 07:17:35

标签: sql postgresql

我正在努力解决问题,但我还是一片空白。我对SQL非常了解,但是我不确定如何实现。

我的问题:

给出一个字符串和一个可能的子字符串表,我需要查找出现的次数。

搜索表由单个列组成:

搜索表

| pattern TEXT PRIMARY KEY|
|-------------------------|
| my                      |
| quick                   |
| Earth                   |

给出字符串“地球是我的星球,我的朋友居住的地方”,预期结果为3(2倍“我”和1倍“地球”)。

在我的函数中,我有可变的bodytext,这是要检查的字符串。

我知道我可以执行IN(从searchtable中选择模式)来获取子字符串的列表,并且我可以使用LIKE ANY子句来获取匹配项,但是如何计算搜索中表中子字符串的出现次数字符串?

2 个答案:

答案 0 :(得分:2)

这很容易完成,而无需自定义功能:

select count(*)
from (values ('Earth is my home planet and where my friends live')) v(str) cross join lateral
     regexp_split_to_table(v.str, ' ') word join
     patterns p
     on word = p.pattern

只需将原始字符串分解为“单词”。然后匹配单词。

另一种方法使用正则表达式匹配:

select (select count(*) from regexp_matches(v.str, p.rpattern, 'g'))
from (values ('Earth is my home planet and where my friends live')) v(str) cross join
     (select string_agg(pattern, '|') as rpattern
      from patterns
     ) p;

这会将所有模式填充到正则表达式中。并不是说这个版本没有考虑断字。

Here是db <>小提琴。

答案 1 :(得分:0)

我用以下代码解决了这个问题:

CREATE OR REPLACE FUNCTION count_matches(body TEXT, OUT matches INTEGER) AS $$
DECLARE
    results INTEGER := 0;
    matchlist RECORD;
BEGIN
FOR matchlist IN (SELECT pattern FROM searchtable)
LOOP
    results := results + (SELECT LENGTH(body) - 
        LENGTH(REPLACE(body, matchlist.pattern, ''))) / 
        LENGTH(matchlist.pattern);
END LOOP;
matches := results;
END;
$$ LANGUAGE plpgsql;