Je vous suggère fortement de consulter cette réponse que j'ai publiée sur "Comment comptez-vous les occurrences d'une chaîne ancrée à l'aide de PostgreSQL ?" . La réponse choisie s'est avérée massivement plus lente qu'une version adaptée de regexp_replace() . La surcharge liée à la création des lignes et à l'exécution de l'agrégat est tout simplement trop élevée.
Le moyen le plus rapide de le faire est le suivant...
SELECT
(length(str) - length(replace(str, replacestr, '')) )::int
/ length(replacestr)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr);
Ici nous
- Prenez la longueur de la chaîne,
L1 - Soustraire de
L1la longueur de la chaîne avec tous les remplacements supprimésL2pour obtenirL3la différence de longueur de chaîne. - Diviser
L3par la longueur du remplacement pour obtenir les occurrences
À titre de comparaison, c'est environ cinq fois plus rapide que la méthode d'utilisation de regexp_matches() qui ressemble à ceci.
SELECT count(*)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr)
CROSS JOIN LATERAL regexp_matches(str, replacestr, 'g');