Pytanie Jak policzyć liczbę wystąpień postaci w wartości varchar Oracle?


Jak mogę policzyć liczbę wystąpień postaci - w ciągu znaków varchar2?

Przykład:

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

27
2017-11-17 15:11


pochodzenie


Jeśli chodzi o występ, to ciekawie znaleźliśmy REGEXP_COUNT rozwiązanie jest około 5 razy wolniejsze (więcej czasu na procesor) niż LENGTH-LENGTH(REPLACE()) podejście. Oracle 11.2.0.4 Linux x86 64-bitowy - Rainer Stenzel


Odpowiedzi:


Proszę bardzo:

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

Technicznie, jeśli ciąg, który chcesz sprawdzić, zawiera tylko znak, który chcesz zliczyć, powyższe zapytanie zwróci wartość NULL; poniższe zapytanie da poprawną odpowiedź we wszystkich przypadkach:

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

Ostateczne 0 w coalesce przechwytuje przypadek, w którym liczysz w pustym ciągu (tj. NULL, ponieważ length (NULL) = NULL w ORACLE).


55
2017-11-17 15:18



Bardzo sprytna ta odpowiedź;) - kevthanewversi


REGEXP_COUNT powinien załatwić sprawę:

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

50
2017-11-17 15:20



Obsługiwany tylko w Oracle 11. Jednak dobre rozwiązanie. - Flukey
+1 dobrze jest wiedzieć, że istnieje również funkcja REGEXP_COUNT. - bpgergo
Wstyd. Nie zauważyłem OP na 10g - Borodin


Oto pomysł: spróbuj zastąpić wszystko, co nie jest znakiem kreskowym z pustym łańcuchem. Następnie policz ile pozostało kresek.

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

10
2017-11-17 15:17





Myślałem o

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

2
2017-11-17 15:22





Podejrzewałem bardzo podobny problem ... ALE RegExp_Count nie mógł go rozwiązać. Ile razy ciąg "16, 124,3,3,1,0" zawiera ", 3"? Jak widzimy 2 razy, ale RegExp_Count zwraca tylko 1. To samo jest z "bbaaaacc" i podczas szukania w nim "aa" - powinno być 3 razy, a RegExp_Count zwraca tylko 2.

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

Straciłem trochę czasu na znalezienie rozwiązania w Internecie. Nie mogłem "znaleźć ... tak napisałem swoją własną funkcję, która zwraca PRAWDZIWĄ liczbę zdarzeń. Mam nadzieję, że będzie użyteczny.

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;

2
2018-01-12 09:32



Wyrażenia regularne działają poprzez przechodzenie przez ciąg, a nie przez rozpoczynanie przeszukiwania na początku za każdym razem, więc REGEXP_COUNT() będzie zawsze i poprawnie (z POV wyrażeń regularnych) powracać 1 na Twój przykład, a także podobne. Znajduje pierwsze wystąpienie ,3,, rozpoczynając od następnej pozycji w łańcuchu, szuka wzoru ponownie i nie znajduje go. - David Faber


tutaj jest rozwiązanie, które będzie działać zarówno dla znaków, jak i dla podciągów:

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

gdzie a jest łańcuchem, w którym przeszukujesz wystąpienie b

miłego dnia!


1
2018-02-26 13:30





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

0
2017-10-31 16:17



Powinieneś również podać kilka wyjaśnień do swojego kodu. - brimborium
Jaka to jest składnia? - collapsar
Powinieneś również podać jakieś wyjaśnienie - Faisal


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
2018-04-27 13:08



Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi. - kayess