Как подсчитать количество вхождений символа -
в строку varchar2?
Пример:
select XXX('123-345-566', '-') from dual;
----------------------------------------
2
Как подсчитать количество вхождений символа -
в строку varchar2?
Пример:
select XXX('123-345-566', '-') from dual;
----------------------------------------
2
Здесь вы идете:
select length('123-345-566') - length(replace('123-345-566','-',null))
from dual;
Технически, если строка, которую вы хотите проверить, содержит только символ, который вы хотите подсчитать, указанный выше запрос возвращает NULL; следующий запрос даст правильный ответ во всех случаях:
select coalesce(length('123-345-566') - length(replace('123-345-566','-',null)), length('123-345-566'), 0)
from dual;
Финал 0 в coalesce
улавливает случай, когда вы подсчитываете пустую строку (т.е. NULL, потому что длина (NULL) = NULL в ORACLE).
REGEXP_COUNT должен сделать трюк:
select REGEXP_COUNT('123-345-566', '-') from dual;
Вот идея: попробуйте заменить все, что не является тире char с пустой строкой. Затем подсчитайте, сколько тире осталось.
select length(regexp_replace('123-345-566', '[^-]', '')) from dual
Я столкнулся с очень похожей проблемой... НО RegExp_Count не смог ее решить. Сколько раз строка '16, 124,3,3,1,0, 'содержит', 3, '? Как мы видим 2 раза, но RegExp_Count возвращает только 1. То же самое происходит с '' bbaaaacc ', а при просмотре' aa '- должно быть 3 раза, а RegExp_Count возвращает только 2.
select REGEXP_COUNT('336,14,3,3,11,0,' , ',3,') from dual;
select REGEXP_COUNT('bbaaaacc' , 'aa') from dual;
Я потерял некоторое время на поиск решения в сети. Не могу найти... поэтому я написал свою собственную функцию, которая возвращает ИСТИННОЕ число вхождения. Надеюсь, это будет полезно.
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;
Я думал о
SELECT LENGTH('123-345-566') - LENGTH(REPLACE('123-345-566', '-', '')) FROM DUAL;
вот решение, которое будет функционировать как для символов, так и для подстрок:
select (length('a') - nvl(length(replace('a','b')),0)) / length('b')
from dual
где a - строка, в которой вы просматриваете появление b
у нас хороший день!
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 ='_';
Вы можете попробовать это
select count( distinct pos) from
(select instr('123-456-789', '-', level) as pos from dual
connect by level <=length('123-456-789'))
where nvl(pos, 0) !=0
он считает "правильно", сколько "аа" в "bbaaaacc"
select count( distinct pos) from
(select instr('bbaaaacc', 'aa', level) as pos from dual
connect by level <=length('bbaaaacc'))
where nvl(pos, 0) !=0