如何统计一个Oracle varchar值中一个字符的出现次数?

问题描述:

如何计算varchar2字符串中字符-的出现次数?如何统计一个Oracle varchar值中一个字符的出现次数?

例子:

select XXX('123-345-566', '-') from dual; 
---------------------------------------- 
2 
+0

关于性能,我们有趣发现'REGEXP_COUNT'溶液为比'LENGTH长度约5倍慢(更CPU耗时)(REPLACE())'的方法。 Oracle 11.2.0.4 Linux x86 64位 –

在这里你去:

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​​3210渔获在那里你在一个空字符串计数的情况下(即NULL,因为长度(NULL)=在ORACLE NULL) 。

+0

非常聪明的答案;) – kevthanewversi

这里有一个想法:尝试更换的一切,是不是一个破折号字符用空字符串。然后计算剩下多少破折号。

select length(regexp_replace('123-345-566', '[^-]', '')) from dual 

REGEXP_COUNT应该做的伎俩:

select REGEXP_COUNT('123-345-566', '-') from dual; 
+3

只在Oracle 11支持。 – Flukey

+0

+1知道还有一个REGEXP_COUNT函数是很好的。 – bpgergo

+0

耻辱。没有注意到OP是在10g – Borodin

我认为

SELECT LENGTH('123-345-566') - LENGTH(REPLACE('123-345-566', '-', '')) FROM DUAL; 

SELECT {FN LENGTH('123-345-566')} - {FN LENGTH({FN REPLACE('123-345-566', '#', '')})} FROM DUAL 
+0

你还应该提供一些解释给你的代码。 – brimborium

+0

这是什么类型的语法? – collapsar

+0

您还应该提供一些解释 – Faisal

这里是将两个字符和子功能的解决方案:

select (length('a') - nvl(length(replace('a','b')),0))/length('b') 
    from dual 

其中a是你在海中的弦r发生b

祝你有美好的一天!

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 ='_'; 
+1

尽管此代码可能会回答问题,但提供有关如何解决问题和/或解决问题原因的其他上下文会提高答案的长期价值。 – kayess

我justed面临非常类似的问题......但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; 

我损失了一些时间在网上研究解决方案。无法找到...所以我写了我自己的函数,返回TRUE发生数。希望它是有用的。

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;