How to count the number of occurrences of a character in an Oracle varchar value?

前端 未结 9 1207
醉梦人生
醉梦人生 2020-12-01 07:35

How can I count number of occurrences of the character - in a varchar2 string?

Example:

select XXX(\'123-345-566\', \'-\') from dual;
--         


        
相关标签:
9条回答
  • 2020-12-01 07:56
    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  ='_';
    
    0 讨论(0)
  • 2020-12-01 07:59

    Here you go:

    select length('123-345-566') - length(replace('123-345-566','-',null)) 
    from dual;
    

    Technically, if the string you want to check contains only the character you want to count, the above query will return NULL; the following query will give the correct answer in all cases:

    select coalesce(length('123-345-566') - length(replace('123-345-566','-',null)), length('123-345-566'), 0) 
    from dual;
    

    The final 0 in coalesce catches the case where you're counting in an empty string (i.e. NULL, because length(NULL) = NULL in ORACLE).

    0 讨论(0)
  • 2020-12-01 08:01

    I justed faced very similar problem... BUT RegExp_Count couldn't resolved it. How many times string '16,124,3,3,1,0,' contains ',3,'? As we see 2 times, but RegExp_Count returns just 1. Same thing is with ''bbaaaacc' and when looking in it 'aa' - should be 3 times and RegExp_Count returns just 2.

    select REGEXP_COUNT('336,14,3,3,11,0,' , ',3,') from dual;
    select REGEXP_COUNT('bbaaaacc' , 'aa') from dual;
    

    I lost some time to research solution on web. Couldn't' find... so i wrote my own function that returns TRUE number of occurance. Hope it will be usefull.

    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;
    
    0 讨论(0)
  • 2020-12-01 08:02
    SELECT {FN LENGTH('123-345-566')} - {FN LENGTH({FN REPLACE('123-345-566', '#', '')})} FROM DUAL
    
    0 讨论(0)
  • 2020-12-01 08:04

    You can try this

    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
    

    it counts "properly" olso for how many 'aa' in '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
    
    0 讨论(0)
  • 2020-12-01 08:07

    I thought of

     SELECT LENGTH('123-345-566') - LENGTH(REPLACE('123-345-566', '-', '')) FROM DUAL;
    
    0 讨论(0)
提交回复
热议问题