Oracle: запрос, который подсчитывает вхождения всех не буквенно-цифровых символов в строке - PullRequest
3 голосов
/ 28 января 2011

Каков наилучший способ подсчета вхождений всех не алфавитно-цифровых символов, которые появляются в строке в столбце базы данных Oracle.

Когда я пытался найти решение, я понял, что у меня есть запрос, не связанный с проблемой, но я заметил, что могу изменить его в надежде решить эту проблему. Я придумал это:

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;

Это работает, чтобы найти ПЕРВЫЙ не алфавитно-цифровой символ, но я хотел бы подсчитать вхождения во всей строке, а не только в первом вхождении. Например в настоящее время мой запрос, анализирующий «a (string)», найдет одну открытую скобку, но мне нужно найти одну открытую скобку и одну закрытую скобку.

Ответы [ 3 ]

5 голосов
/ 28 января 2011

Существует неясная функция Oracle TRANSLATE, которая позволит вам сделать это вместо регулярного выражения:

select a.*,
       length(translate(lower(title),'.0123456789abcdefghijklmnopqrstuvwxyz','.')) 
from table_name a
4 голосов
/ 28 января 2011

Попробуйте это:

SELECT  a.*, LENGTH(REGEXP_REPLACE(TITLE, '[^a-zA-Z0-9]'), '')
FROM    TABLE_NAME a
1 голос
/ 31 января 2011

Наилучшим вариантом, как вы обнаружили, является использование процедуры PL / SQL.Я не думаю, что есть какой-либо способ создать выражение регулярного выражения, которое будет возвращать несколько значений, как вы ожидаете (по крайней мере, не в Oracle).

Один из способов обойти это - использовать рекурсивный запросисследовать каждый символ индивидуально, что может быть использовано для возврата строки для каждого найденного символа.Следующий пример будет работать для одной строки:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...