как извлечь уникальные слова из клетки и посчитать их - PullRequest
0 голосов
/ 15 мая 2019

У меня есть столбец "DESCRIPTION" (VARCHAR2 (500 Byte))

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

Дополнительно у меня есть ограничивающий параметр "ENTRYDATE" (i.e. "WHERE ENTRYDATE BETWEEN 20180101 and 20190101"). Поскольку таблица довольно большая.

У меня есть какое-то решение в Excel, но это грязно и больно.

Можно ли вообще сделать это в Oracle с помощью SELECT?

Пример:

КОЛИЧЕСТВО КОЛОННЫ |ОБЪЯСНЕНИЕ

1 | roses are red violets are blue
2 | red violets 
3 | red
4 | roses
5 | blue

РЕЗУЛЬТАТ:

WORDS | COUNTING

roses | 2
are | 2
red | 3
violets | 2
blue | 2

Вариация запроса:

with test as
      (select 1 as nor, 'roses are red violets are blue' as explanation from dual union all
       select 2 as nor, 'red violets' as explanation from dual union all
       select 3 as nor, 'red'  as explanation from dual union all
       select 4 as nor, 'roses'  as explanation from dual union all
       select 5 as nor, 'blue'   as explanation from dual
      ),
    temp as
      (select nor,
             trim(column_value) word
      from test join xmltable(('"' || replace(explanation, ' ', '","') ||'"')) on 1 = 1
     )
   select word,
          count(*)
   from temp
   group by word
   order by word;

возвращает ORA-00905: отсутствует ключевое слово

Ответы [ 3 ]

0 голосов
/ 15 мая 2019
-- Oracle 12c+
with test (nor, explanation) as (
select 1, 'roses are red violets are blue' from dual union all
select 2, 'red violets'                    from dual union all
select 3, 'red'                            from dual union all
select 4, 'roses'                          from dual union all
select 5, 'blue'                           from dual)
select regexp_substr(explanation, '\S+', 1, lvl) word, count(*) cnt
from test,
lateral(
select rownum lvl
from dual
connect by level <= regexp_count(explanation, '\S+')
)
group by regexp_substr(explanation, '\S+', 1, lvl);

WORD                                  CNT
------------------------------ ----------
roses                                   2
are                                     2
violets                                 2
red                                     3
blue                                    2
0 голосов
/ 15 мая 2019

Проблема в вашей старой версии Oracle.Этот запрос должен работать, он имеет только базовые connect by, instr и dbms_random:

select word, count(1) counting
  from (
    select id, trim(case pos2 when 0 then substr(description, pos1) 
                              else substr(description, pos1, pos2 - pos1) 
                    end) word
      from (
        select id, description, 
               case level when 1 then 1 else instr(description, ' ', 1, level - 1) end pos1, 
               instr(description, ' ', 1, level) pos2
          from t 
          connect by prior dbms_random.value is not null 
                 and prior id = id 
                 and level <= length(description) - length(replace(description, ' ', '')) + 1))
  group by word

демо

0 голосов
/ 15 мая 2019

Разбейте объяснение на строки (чтобы вы получили слов ), затем примените к этим словам функцию COUNT.

SQL> with test (nor, explanation) as
  2    (select 1, 'roses are red violets are blue' from dual union all
  3     select 2, 'red violets'                    from dual union all
  4     select 3, 'red'                            from dual union all
  5     select 4, 'roses'                          from dual union all
  6     select 5, 'blue'                           from dual
  7    ),
  8  temp as
  9    (select nor,
 10            regexp_substr(explanation, '[^ ]+', 1, column_value) word
 11     from test join table(cast(multiset(select level from dual
 12                                        connect by level <= regexp_count(explanation, ' ') + 1
 13                                       ) as sys.odcinumberlist)) on 1 = 1
 14    )
 15  select word,
 16         count(*)
 17  from temp
 18  group by word
 19  order by word;

WORD                             COUNT(*)
------------------------------ ----------
are                                     2
blue                                    2
red                                     3
roses                                   2
violets                                 2

SQL>

Вы упомянули столбец entrydate, но в данных образца его нет, поэтому - при необходимости включите его в TEMP CTE.

[РЕДАКТИРОВАТЬ: Да, Oracle 9i ... вернуться к темные века ]

Посмотрите, поможет ли это; Я надеюсь, что это делает:

SQL> with test (nor, explanation) as
  2    (select 1, 'roses are red violets are blue' from dual union all
  3     select 2, 'red violets'                    from dual union all
  4     select 3, 'red'                            from dual union all
  5     select 4, 'roses'                          from dual union all
  6     select 5, 'blue'                           from dual
  7    ),
  8  temp as
  9    (select nor,
 10            trim(column_value) word
 11     from test join xmltable(('"' || replace(explanation, ' ', '","') ||'"')) on 1 = 1
 12    )
 13  select word,
 14         count(*)
 15  from temp
 16  group by word
 17  order by word;

WORD                   COUNT(*)
-------------------- ----------
are                           2
blue                          2
red                           3
roses                         2
violets                       2

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...