We know the stringutils function CountMatches() - CountMatches - counts the number of occurrences of one String in another. I need an equivalent query in postgresql to count the number of occurence of a string in another.
Any idea would appreciated
We know the stringutils function CountMatches() - CountMatches - counts the number of occurrences of one String in another. I need an equivalent query in postgresql to count the number of occurence of a string in another.
Any idea would appreciated
On
regexp_matches()The solution with regexp_matches() that @Igor suggested and @Tomasz implemented is short and elegant, but has two downsides:
To use it in a query with multiple source rows:
SELECT t.*, count(match) AS ct
FROM tbl t
LEFT JOIN LATERAL regexp_matches(t.string, 'ab', 'g') match ON TRUE
GROUP BY t.tbl_id
ORDER BY t.tbl_id;
Or:
SELECT t.*, m.ct
FROM tbl t
LEFT JOIN LATERAL (
SELECT count(*) AS ct
FROM regexp_matches(t.string, 'ab', 'g')
) m ON TRUE
ORDER BY t.tbl_id;
replace() / length()The expression is not as elegant, but should be faster and can be used on sets more easily:
SELECT (length(col) - length(replace(col, 'match', ''))) / length('match') AS ct;
You can wrap this in a simple SQL function:
CREATE OR REPLACE FUNCTION f_count_matches(_string text, _match text)
RETURNS int LANGUAGE sql IMMUTABLE STRICT AS
$$
SELECT (length(_string) - length(replace(_string, _match, ''))) / length(_match)
$$;
Then:
SELECT f_count_matches('abc cab,xabx abab', 'ab');
SQL Fiddle demonstrating all.
PostgreSQL does not have that function, but you can work around it this way:
There may be edge cases that do not work correctly.
regexp_split_to_arraycreates an array with the non-matching parts. The number of elements in the array is one more than the number of matches (at least for normal cases). So,array_lengthand-1produce the count of matches.