Запрос подсчета различных значений в столбце Oracle db CLOB - PullRequest
0 голосов
/ 09 апреля 2019

Я бы хотел запросить в таблице БД Oracle количество строк, содержащих каждое отдельное значение в столбце CLOB.

Возвращает все строки, содержащие значение:

select * from mytable where dbms_lob.instr(mycol,'value') > 0;

Использование DBMS_LOB , это возвращает количество строк, содержащих это значение:

select count(*) from mytable where dbms_lob.instr(mycol,'value') > 0;

Но возможно ли запросить количество раз (строк, в которых) появляется каждое отдельное значение?

Ответы [ 3 ]

2 голосов
/ 09 апреля 2019

Стандартные функции Oracle не поддерживают различие значений CLOB.Но, если у вас есть доступ к функции DBMS_CRYPTO.HASH, вы можете вместо этого сравнить CLOB-хэши и получить желаемый результат:

select myCol, h.num from
   myTable t join 
      (select min(rowid) rid, count(rowid) num
              from myTable
       where dbms_lob.instr(mycol,'value') > 0
       group by DBMS_CRYPTO.HASH(myCol, 3)) h
   on t.rowid = h.rid;

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

2 голосов
/ 09 апреля 2019

Если ваши значения CLOB больше 4000 байтов (а если нет, то почему они являются CLOB?), То это не идеально - возможны коллизии, если маловероятно, - но вы можете хешировать значения CLOB.

Если вы хотите посчитать количество различных значений:

select count(distinct dbms_crypto.hash(src=>mycol, typ=>2))
from mytable
where dbms_lob.instr(mycol,'value') > 0;

Если вы хотите посчитать, сколько раз появляется каждое отдельное значение:

select mycol, cnt
from (
  select mycol,
    count(*) over (partition by dbms_crypto.hash(src=>mycol, typ=>2)) as cnt,
    row_number() over (partition by dbms_crypto.hash(src=>mycol, typ=>2) order by null) as rn
  from mytable
  where dbms_lob.instr(mycol,'value') > 0
)
where rn = 1;

Оба варианта могут быть довольно дорогими и медленными с большим количеством данных.

(typ=>2 дает числовое значение для dbms_crypto.hash_md5, поскольку вы не можете ссылаться на константу пакета в вызове SQL, по крайней мере, до 12cR1 ...)


Скорее, грубее, но, возможно, значительно быстрее, вы можете основывать счет только на первых 4000 символах - что может или не может быть правдоподобно для ваших фактических данных:

select count(distinct dbms_lob.substr(mycol, 4000, 1))
from mytable
where dbms_lob.instr(mycol,'value') > 0;

select dbms_lob.substr(mycol, 4000, 1), count(*)
from mytable
where dbms_lob.instr(mycol,'value') > 0
group by dbms_lob.substr(mycol, 4000, 1);
2 голосов
/ 09 апреля 2019

В зависимости от того, что действительно содержит этот столбец, посмотрите, поможет ли TO_CHAR.

SQL> create table mytable (mycol clob);

Table created.

SQL> insert into mytable
  2    select 'Query to count distinct values' from dual union all
  3    select 'I have no idea which values are popular' from dual;

2 rows created.

SQL>  select count(*), to_char(mycol) toc
  2  from mytable
  3  where dbms_lob.instr(mycol,'value') > 0
  4  group by to_char(mycol);

  COUNT(*) TOC
---------- ----------------------------------------
         1 Query to count distinct values
         1 I have no idea which values are popular

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