Как подсчитать каждое вхождение слова в строку в цикле ORACLE? - PullRequest
0 голосов
/ 23 января 2012

У меня проблема, которая на первый взгляд кажется простой, но на самом деле это не так.Я храню слова в таблице таким образом, что пара строк "ABCDE" и "DEF" становится:

id  value
--  -----
1   A
1   B
1   C
1   D
1   E
2   D
2   E
2   F

И я перехожу к моей строке процедуры ORACLE, которая выглядит так: "ABCDG".А теперь я хочу проверить процент сходства между строками в базе данных и строкой, переданной в качестве параметра.

Я предполагаю, что мне нужно использовать одну из функций разбиения и использовать массив.Позже проверим, встречается ли каждое слово в переданной строке в таблице, а затем посчитаем идентификаторы.Но есть поворот: мне нужно точное процентное значение.

Итак, результат из приведенного выше примера должен выглядеть следующим образом:

id percentage
-- ----------
1  80              -- 4 out of 5 letters exists in query string (A B C D)
2  33              -- 1 out of 3 (D)

Итак, мои вопросы:

  • Какой самый эффективный способ разбить строку запросаа затем выполнить итерации (таблица?)
  • как сохранить частичные результаты и затем подсчитать их?
  • как подсчитать окончательное процентное значение?

Каждая помощь будетс благодарностью.

Ответы [ 2 ]

2 голосов
/ 23 января 2012

Следующий запрос даст вам то, что вы хотите, без необходимости беспокоиться о процедурах.

select id
     , sum(case when value in ('A', 'B', 'C', 'D', G') then 1 else 0 ) / count(*)
  from my_table
 group by id

В качестве альтернативы, если у вас есть для передачи строки "ABCDG" и получения результатаназад вы могли бы сделать:

select id
     , sum(case when instr('A B C D G', value) <> 0 then 1 else 0 ) / count(*)
  from my_table
 group by id

Они включают в себя полное сканирование таблицы или полное сканирование индекса, если вы используете предложенный индекс ниже, поэтому вы можете добавить следующую фразу where, если хотите найти толькоids с процентами> 0.

select id
     , sum(case when instr('A B C D G', value) <> 0 then 1 else 0 ) / count(*)
  from my_table
 where exists ( select 1
                  from my_table
                 where id = mt.id
                   and instr('A B C D G', value) <> 0 )
 group by id

Для всех запросов ваша таблица должна быть проиндексирована на my_table, id в этом порядке.

0 голосов
/ 23 января 2012

Вы смотрели на UTL_MATCH ? Это не делает именно то, что вы пытаетесь достичь, но вы можете найти это полезным, если определение вашего процентного соглашения не в камне.

...