我正在努力解决问题,但我还是一片空白。我对SQL非常了解,但是我不确定如何实现。
我的问题:
给出一个字符串和一个可能的子字符串表,我需要查找出现的次数。
搜索表由单个列组成:
搜索表
| pattern TEXT PRIMARY KEY| |-------------------------| | my | | quick | | Earth |
给出字符串“地球是我的星球,我的朋友居住的地方”,预期结果为3(2倍“我”和1倍“地球”)。
在我的函数中,我有可变的bodytext,这是要检查的字符串。
我知道我可以执行IN(从searchtable中选择模式)来获取子字符串的列表,并且我可以使用LIKE ANY子句来获取匹配项,但是如何计算搜索中表中子字符串的出现次数字符串?
答案 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;