Oracle: Eine Abfrage, die das Vorkommen aller nicht alphanumerischen Zeichen in einer Zeichenfolge zählt
-
27-10-2019 - |
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.
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