Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Поиск повторяющихся значений / 20 сообщений из 20, страница 1 из 1
26.09.2017, 18:44
    #39526696
leprechaun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Добрый день, не соображу пока, мне нужно в списке наименований найти к примеру те, у которых совпадает 5 последовательных символов. Как это оформить, спасибо
...
Рейтинг: 0 / 0
26.09.2017, 19:46
    #39526729
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Как это оформить

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with t as (
       select 'abcde12345' name from dual union all
       select 'bcde1234567' name from dual union all
       select 'qwecde123777' name from dual union all
       select '12345678abc' name from dual union all
       select '678abcdeqwe' name from dual
     )
select t1.name, t2.name from t t1, t t2



Дальше специалисты по REGEXP подтянутся.
...
Рейтинг: 0 / 0
26.09.2017, 19:55
    #39526734
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
...
Рейтинг: 0 / 0
26.09.2017, 20:00
    #39526739
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Код: plaintext
1.
2.
3.
4.
5.
6.
with t(name) as
(select 'abbbbc' from dual
union all select 'abbbbbc' from dual
union all select 'abbbbbbc' from dual)
select t.*,
       case when regexp_like(name, '(.)\1{4}') then 1 end "5_or_more"
  from t
...
Рейтинг: 0 / 0
26.09.2017, 21:14
    #39526757
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
dmdmdm Как это оформить

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with t as (
       select 'abcde12345' name from dual union all
       select 'bcde1234567' name from dual union all
       select 'qwecde123777' name from dual union all
       select '12345678abc' name from dual union all
       select '678abcdeqwe' name from dual
     )
select t1.name, t2.name from t t1, t t2



Дальше специалисты по REGEXP подтянутся.

Если понимать задачу, как поиск совпадения последовательности из 5 символов в разных полях, то можно и без regexp:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
with t as
 (select 'abcde12345' name, 1 as n
    from dual
  union all
  select 'bcde1234567' name, 2
    from dual
  union all
  select 'qwecde123777' name, 3
    from dual
  union all
  select '12345678abc' name, 4
    from dual
  union all
  select '678abcdeqwe' name, 5
    from dual)
select t1.name, t2.name
  from t t1, t t2
 where t1.name != t2.name
   and t1.name like '%' || substr(t2.name, level, 5) || '%'
connect by t1.name != t2.name
       and level <= length(t2.name) - 5
       and prior t2.name = t2.name
       and prior t1.name = t1.name
       and prior t1.name = t2.name
 order by t1.n


номер и сортировку по нему добавил для облегчения визуальной сверки
...
Рейтинг: 0 / 0
26.09.2017, 22:46
    #39526778
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Fogel,

Код: plsql
1.
and level <= length(t2.name) - 4 -- a не and level <= length(t2.name) - 5



SY.
...
Рейтинг: 0 / 0
27.09.2017, 00:29
    #39526810
leprechaun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Спасибо! Не то чтоб код был для меня прозрачен, но опробую завтра.
...
Рейтинг: 0 / 0
27.09.2017, 02:03
    #39526821
Sergei.Agalakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Насколько часто надо искать? В принципе можно создать доменные индексы, если надо часто выполнять такие запросы.
...
Рейтинг: 0 / 0
27.09.2017, 02:30
    #39526824
leprechaun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Довольно часто, регулярный запрос
...
Рейтинг: 0 / 0
27.09.2017, 10:24
    #39526928
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaun,

символы в том числе буквы?
тогда нужено учитывать на каком языке алфавит
напр на украинском "зиіїй" подряд пьять букв, такая строка должна попасть в выборку?

опять ж, upper/lower учитывать?

или "у которых совпадает 5 последовательных символов" ето "ашшшшшб"?

.....
stax
...
Рейтинг: 0 / 0
27.09.2017, 13:26
    #39527090
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
SYFogel,

Код: plsql
1.
and level <= length(t2.name) - 4 -- a не and level <= length(t2.name) - 5



SY.

не.
хоть минус 10000
единственное НО - этот запрос до первого уникального вхождения, если совпадения по нескольким последовательностям - все пары не покажет.
Чтобы увидеть все совпадения (в том числе дубли полей) - лучше тогда отталкиваться от общей последовательности и оформить, например так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
with t as
 (select 'abcde12345' name
    from dual
  union all
  select '12345' name
    from dual
  union all
  select 'xxxxxx12345zzz678abzz' name
    from dual
  union all
  select 'bcde1234567' name
    from dual
  union all
  select 'qwecde123777' name
    from dual
  union all
  select '12345678abc' name
    from dual
  union all
  select '678abcdeqwe' name
    from dual),
list_seq as (select substr(t2.name, level, 5) as a5
  from t t1, t t2
 where t1.name != t2.name
   and instr(t1.name, substr(t2.name, level, 5)) > 0
connect by level < length(t2.name)
       and prior t2.name = t2.name
       and prior t1.name = t1.name
       and prior t1.name = t2.name
       group by substr(t2.name, level, 5)) 
select l.a5, listagg(t.name,',') within group (order by t.name) from t, list_seq l where instr(t.name,l.a5) > 0
group by l.a5


ну или наоборот, в каком поле какой набор общих последовательностей:
Код: plsql
1.
2.
3.
...
select t.name, listagg(l.a5,',') within group (order by l.a5) as seq from t, list_seq l where instr(t.name,l.a5) > 0
group by t.name 
...
Рейтинг: 0 / 0
27.09.2017, 17:17
    #39527234
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Fogelне.
хоть минус 10000


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  1  with t1 as (
  2  select '1234567' name from dual)
  3  select rownum l,substr(name, level, 5) s from t1
  4* connect by level < length(t1.name)
SQL> /

         L S
---------- -----
         1 12345
         2 23456
         3 34567
         4 4567
         5 567
         6 67

6 rows selected.



для 4, 5, 6 нет смысла искать вхождение, поетому length-3


......
stax
...
Рейтинг: 0 / 0
27.09.2017, 18:08
    #39527254
leprechaun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
to Fogel подвис у меня что-то такой код, не хватило ресурсов выполнить (Connect by filtering phase runs out of temp tablespace)

Еще раз уточню вопрос, есть список допустим номенклатуры.
И нужно передавая в параметре количество искомых символов, выводить все позиции
к примеру 3 передал, получил

Молоко
Молоток
Виноград Молдова
...
Рейтинг: 0 / 0
27.09.2017, 18:33
    #39527266
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaun,

Наибольшая общая подпоследовательность
На англоязычной википедии статья намного полезнее.

В интере можно найти несколько SQL решений которые не стоит воспринимать серьезно.
Чуть улучшить можно используя model clause, но если задача имеет практический смысл - лучше сделать PL/SQL или C function.
...
Рейтинг: 0 / 0
28.09.2017, 10:35
    #39527510
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaun,

сколько "последовательностей"?
select sum(length(name)-:n+1) from t

и скоко строк в справочнике?

если не надо выводить из-за чего повторение,
попробовать переписать через exists в надежде что, если пересеклось то дальше не ищем

.....
stax
...
Рейтинг: 0 / 0
28.09.2017, 11:03
    #39527534
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaunЕще раз уточню вопрос

с кем совпадает надо вывадить?

.....
stax
...
Рейтинг: 0 / 0
28.09.2017, 11:26
    #39527548
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaun,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
with t as (
select 1 id, 'Молоко' name from dual union all
select 2,'Молоток'  from dual union all
select 3,'Виноград Молдова'  from dual union all
select 4,'Золотo'  from dual union all
select 5,'1234567'  from dual union all
select 6,'7654321'  from dual union all
select 7,'000654654000'  from dual union all
select 8,'9876'  from dual 
)
select * from t
where
exists (
   select 1 from t tt
   where tt.id<>t.id and instr(t.name,substr(tt.name,level,3))>0
connect by tt.id=prior tt.id and level<=length(tt.name)-2 and prior sys_guid() is not null)
/
SQL> /

        ID NAME
---------- ----------------
         1 Молоко
         2 Молоток
         3 Виноград Молдова
         4 Золотo
         6 7654321
         7 000654654000




.....
stax
...
Рейтинг: 0 / 0
28.09.2017, 20:17
    #39527930
leprechaun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Stax

Да, надо выводить с кем совпадает, и думаю не до первого совпадения, а все. В справочнике может быть тысяч 50 наименований, я пока без понятия как сделать, твой код посмотрю, спасибо.
...
Рейтинг: 0 / 0
28.09.2017, 21:36
    #39527945
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
Можно заюзать текстовые индексы:
например, для поиска от 3-букв:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
create table dict as 
select 1 id, 'Молоко' name from dual union all
select 2,'Молоток'  from dual union all
select 3,'Виноград Молдова'  from dual union all
select 4,'Золотo'  from dual union all
select 5,'1234567'  from dual union all
select 6,'7654321'  from dual union all
select 7,'000654654000'  from dual union all
select 8,'9876'  from dual 
/
begin 
   ctx_ddl.create_preference('worlist_substr', 'BASIC_WORDLIST'); 
   ctx_ddl.set_attribute('worlist_substr','PREFIX_INDEX','TRUE');
   ctx_ddl.set_attribute('worlist_substr','PREFIX_MIN_LENGTH', '3');
   ctx_ddl.set_attribute('worlist_substr','PREFIX_MAX_LENGTH', '20');
   ctx_ddl.set_attribute('worlist_substr','SUBSTRING_INDEX', 'YES');
end;
/
create index ix_dict_ctx on dict(name)
indextype is ctxsys.context
parameters('WORDLIST worlist_substr SYNC (on commit)')
/


после этого появится таблица с токенами DR$ IX_DICT_CTX $I, по ней и можно легко искать:
вариант 1
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
with tokens as (
   select
     token_text
    ,token_type
    ,sum(token_count) cnt
   from DR$IX_DICT_CTX$I t
   where length(token_text)=3
   group by token_text, token_type
   having sum(token_count)>1
)
select t.*
      ,x.*
      ,d.name
from tokens t
     ,xmltable('/CTXREPORT/TOKEN_INFO/TOKEN_DATA/TOKEN_DATA_ROW/TOKEN_DATA_DOCID'
               passing 
               xmltype(
                        ctx_report.token_info(
                             index_name => 'IX_DICT_CTX'
                            ,token      => t.token_text
                            ,token_type => t.token_type
                            ,report_format=>'XML'
                            )
                      )
               columns rid rowid path '@BASE_ROWID'
              ) x
     ,dict d
where x.rid = d.rowid
/


вариант 2
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with tokens as (
   select
     token_text
    ,token_type
    ,sum(token_count) cnt
   from DR$IX_DICT_CTX$I t
   where length(token_text)=3
   group by token_text, token_type
   having sum(token_count)>1
)
select t.*
      ,d.name
from tokens t, dict d
where contains(d.name,'%'||t.token_text||'%')>0

...
Рейтинг: 0 / 0
29.09.2017, 09:19
    #39528097
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск повторяющихся значений
leprechaunStax

Да, надо выводить с кем совпадает, и думаю не до первого совпадения, а все. В справочнике может быть тысяч 50 наименований, я пока без понятия как сделать, твой код посмотрю, спасибо.

запрос похож на Fogel (переписал для exists)

по любому надо сравнивать каждую строку с каждой, а ето 50000*50000=2 500 000 000, при етом еще разложить на "5-ти символьные", многовато

можно немного уменьшить с учетом если А пересекается с Б, то и Б с А

как советовали, просить права и создавать ф-цию, и експерементировать напр с pipelined + parallel

если поиск разовый, можно напр ночью искать

.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Поиск повторяющихся значений / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]