Oracle: Eine Abfrage, die das Vorkommen aller nicht alphanumerischen Zeichen in einer Zeichenfolge zählt

StackOverflow https://stackoverflow.com/questions/4831362

Frage

Was wäre der beste Weg, um Ereignisse aller nicht alphanumerischen Zeichen zu zählen, die in einer String in einer Spalte von Oracle -Datenbank erscheinen.

Als ich versuchte, eine Lösung zu finden, wurde mir klar, dass ich eine Frage hatte, die nichts mit dem Problem zu tun hatte, aber ich bemerkte, dass ich sie ändern konnte, in der Hoffnung, dieses Problem zu lösen. Ich habe das gekommen:

SELECT  COUNT (*), SUBSTR(TITLE, REGEXP_INSTR(UPPER(TITLE), '[^A-Z,^0-9]'), 1)
FROM    TABLE_NAME
WHERE   REGEXP_LIKE(UPPER(TITLE), '[^A-Z,^0-9]')
GROUP BY    SUBSTR(TITLE, REGEXP_INSTR(UPPER(TITLE), '[^A-Z,^0-9]'), 1)
ORDER BY COUNT(*) DESC;

Dies funktioniert, um den ersten nicht alphanumerischen Charakter zu finden, aber ich möchte die Ereignisse während der gesamten Saite zählen, nicht nur das erste Ereignis. Z.B. Derzeit würde meine Abfrage, die "A (String)" analysiert, eine offene Klammung finden, aber ich brauche sie, um eine offene Klammer und eine geschlossene Klammern zu finden.

War es hilfreich?

Lösung

Die beste Option, wie Sie festgestellt haben, ist die Verwendung eines PL/SQL -Verfahrens. Ich glaube nicht, dass es eine Möglichkeit gibt, einen Regex -Ausdruck zu erstellen, der mehrere Zählungen zurückgibt, wie Sie es erwarten (zumindest nicht in Oracle).

Eine Möglichkeit, dies zu umgehen, besteht darin, eine rekursive Abfrage zu verwenden, um jedes Zeichen einzeln zu untersuchen, mit der eine Zeile für jeden gefundenen Zeichen zurückgegeben werden kann. Das folgende Beispiel funktioniert für eine einzelne Zeile:

with d as (
   select '(1(2)3)' as str_value
   from dual)
select char_value, count(*)
from (select substr(str_value,level,1) as char_value
      from d
      connect by level <= length(str_value))
where regexp_instr(upper(char_value), '[^A-Z,^0-9]'), 1) <> 0
group by char_value;

Andere Tipps

Es gibt eine obskure Oracle Translate -Funktion, mit der Sie dies anstelle von Regexp tun können:

select a.*,
       length(translate(lower(title),'.0123456789abcdefghijklmnopqrstuvwxyz','.')) 
from table_name a

Versuche dies:

SELECT  a.*, LENGTH(REGEXP_REPLACE(TITLE, '[^a-zA-Z0-9]'), '')
FROM    TABLE_NAME a
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top