Comment compter le nombre d'occurrences d'un caractère dans un Oracle valeur varchar?
Comment puis-je compter le nombre d'occurrences du caractère -
dans une chaîne de caractères varchar2?
Exemple:
select XXX('123-345-566', '-') from dual;
----------------------------------------
2
8 réponses
Ici, vous allez:
select length('123-345-566') - length(replace('123-345-566','-',null))
from dual;
techniquement, si la chaîne que vous voulez vérifier Ne contient que le caractère que vous voulez compter, la requête ci-dessus retournera NULL; la requête suivante donnera la bonne réponse dans tous les cas:
select coalesce(length('123-345-566') - length(replace('123-345-566','-',null)), length('123-345-566'), 0)
from dual;
La finale 0 coalesce
capte le cas où vous comptez dans une chaîne vide (i.e. NULL, parce que length(NULL) = NULL dans ORACLE).
REGEXP_COUNT devrait faire l'affaire:
select REGEXP_COUNT('123-345-566', '-') from dual;
voici une idée: essayer de remplacer tout ce qui n'est pas un char de tableau de bord par une chaîne vide. Puis comptez le nombre de tirets restants.
select length(regexp_replace('123-345-566', '[^-]', '')) from dual
j'ai pensé à
SELECT LENGTH('123-345-566') - LENGTH(REPLACE('123-345-566', '-', '')) FROM DUAL;
je viens de faire face à un problème très similaire... Mais RegExp_Count n'a pas pu le résoudre. Combien de fois la chaîne '16,124,3,3,1,0,' contient ',3,'? Comme nous le voyons 2 fois, mais RegExp_Count retourne seulement 1. La même chose est avec "bbaaaacc" et en regardant dans 'aa' - devrait être 3 fois et RegExp_Count retourne seulement 2 fois.
select REGEXP_COUNT('336,14,3,3,11,0,' , ',3,') from dual;
select REGEXP_COUNT('bbaaaacc' , 'aa') from dual;
j'ai perdu du temps à rechercher des solutions sur le web. Ne pouvais pas trouver... j'ai donc écrit ma propre fonction qui renvoie le nombre réel d'occurance. Espérons qu'il sera utile.
CREATE OR REPLACE FUNCTION EXPRESSION_COUNT( pEXPRESSION VARCHAR2, pPHRASE VARCHAR2 ) RETURN NUMBER AS
vRET NUMBER := 0;
vPHRASE_LENGTH NUMBER := 0;
vCOUNTER NUMBER := 0;
vEXPRESSION VARCHAR2(4000);
vTEMP VARCHAR2(4000);
BEGIN
vEXPRESSION := pEXPRESSION;
vPHRASE_LENGTH := LENGTH( pPHRASE );
LOOP
vCOUNTER := vCOUNTER + 1;
vTEMP := SUBSTR( vEXPRESSION, 1, vPHRASE_LENGTH);
IF (vTEMP = pPHRASE) THEN
vRET := vRET + 1;
END IF;
vEXPRESSION := SUBSTR( vEXPRESSION, 2, LENGTH( vEXPRESSION ) - 1);
EXIT WHEN ( LENGTH( vEXPRESSION ) = 0 ) OR (vEXPRESSION IS NULL);
END LOOP;
RETURN vRET;
END;
voici une solution qui fonctionnera à la fois pour les caractères et les substrats:
select (length('a') - nvl(length(replace('a','b')),0)) / length('b')
from dual
où a est la chaîne dont vous recherchez l'occurrence de b
bonne journée!
SELECT {FN LENGTH('123-345-566')} - {FN LENGTH({FN REPLACE('123-345-566', '#', '')})} FROM DUAL
select count(*)
from (
select substr('K_u_n_a_l',level,1) str
from dual
connect by level <=length('K_u_n_a_l')
)
where str ='_';