Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > кол-во вхождений слов из строки в текстовом поле


Автор: s_a_s_h_a 14.9.2009, 20:56
Есть текстовое поле P в таблице A. Есть строка B из слов b[i]. Необходимо получить кортеж таблицы А и для каждого кортежа количество вхождений слов b[i] в поле P таблицы A.

Например:

Таблица А:   id |    val    |     P
                     ---------------------
                     1  |    v1     | яблоко апельсин
                     2  |    v2     | апельсин ананас
                     3  |    v3     | апельсин яблоко ананас арбуз

строка B:  "арбуз яблоко апельсин"

Должен получиться результат

                     id |    val    |                          P                        |  count
                     --------------------------------------------------------------------
                     1  |    v1     | яблоко апельсин                        |   2
                     2  |    v2     | апельсин ананас                        |  1
                     3  |    v3     | апельсин яблоко ананас арбуз |   3

Можно ли сделать это средствами PL/SQL? 

P.S.: Oracle  9

Автор: Gudinya 14.9.2009, 23:45
Написал в ужасном стиле, может и не самый оптимальный вариант, но вроде должно работать smile

Код

create table temp_table(
text varchar2(100));

insert into temp_table(text) values ('яблоко апельсин');
insert into temp_table(text) values ('апельсин ананас');
insert into temp_table(text) values ('апельсин яблоко ананас арбуз');

create or replace function InstrCount(str1 varchar2, str2 varchar2) return number
as
  txt1 varchar2(100);
  txt2 varchar2(100);
  txt2tmp varchar2(100);
  s1 varchar2(100);
  s2 varchar2(100);
  WordsInStr1 number;
  WordsInStr2 number;
  cnt number := 0;
begin
  txt1 := str1 ||' ';
  txt2 := str2 ||' ';
  WordsInStr1 := length(txt1) - length(replace(txt1,' '));
  WordsInStr2 := length(txt2) - length(replace(txt2,' '));

  for i in 0..WordsInStr1 loop
    s1 := substr(txt1, 1, instr(txt1, ' ') - 1);
    txt1 := substr(txt1, length(s1) + 2);
    txt2tmp := txt2;
    for j in 0..WordsInStr2 loop
      s2 := substr(txt2tmp, 1, instr(txt2tmp, ' ') - 1);
      txt2tmp := substr(txt2tmp, length(s2) + 2);
      if s1 = s2 then
        cnt := cnt + 1;
      end if;
    end loop;
  end loop;
  return cnt;
end;
/

select t.*, InstrCount(t.text, 'арбуз яблоко апельсин') from temp_table t;



Автор: Zloxa 15.9.2009, 08:55
Цитата(s_a_s_h_a @  14.9.2009,  20:56 Найти цитируемый пост)
Oracle  9 

Код

SQL> with
  2  str as (select 'арбуз яблоко апельсин' str from dual)
  3  ,src as (
  4     select  1 id, 'яблоко апельсин' p from dual
  5     union all  select 2 id, 'апельсин ананас' p from dual
  6     union all  select 3 id, 'апельсин яблоко ананас арбуз' p from dual
  7  )
  8  select id,max(P) p,count(str.w) c
  9  from (
 10    select id,p,substr(p,instr(' '||p,' ',1,level),instr(p||' ',' ',1,level) -instr(' '||p,' ',1,level)) w
 11    from src
 12      connect by instr(' '||p,' ',1,level) > 0
 13          and prior id = id
 14          and prior sys_guid() is not null
 15       ) s
 16   left join (select substr(str,instr(' '||str,' ',1,level),instr(str||' ',' ',1,level) -instr(' '||str,' ',1,level)) w
 17                from str
 18                connect by instr(' '||str,' ',1,level) > 0) str
 19    on s.w = str.w
 20  group by id
 21  ;
 
        ID P                                     C
---------- ---------------------------- ----------
         1 яблоко апельсин                       2
         2 апельсин ананас                       1
         3 апельсин яблоко ананас арбуз          3
 
SQL> 

Автор: s_a_s_h_a 15.9.2009, 11:08
Спасибо. Буду разбираться.


Zloxa, смутили строки с 3 по 7. Строк в таблице может быть N.

Автор: DimW 15.9.2009, 11:18
Цитата(s_a_s_h_a @  15.9.2009,  11:08 Найти цитируемый пост)
Строк в таблице может быть N. 

ну так подставьте вместо src свою таблицу в запрос.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)