Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 поиск трех подряд идущих букв алфавита  [new]
infantis
Member

Откуда: Санкт-Петербург
Сообщений: 4
Помогите, пожалуйста, составить запрос для поиска среди символьных констант тех, которые имеют в содержании три подряд идущие буквы алфавита.
Например: 'gfdhgabcgfs', 'hds9f0-9xyz'. Спасибо
19 июн 10, 19:23    [8968481]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
AmKad
Member

Откуда:
Сообщений: 5222
infantis,

Вот мой вариант (возможно не самый лучший):
with s as
(select 1 id, 'abcfrf'  str from dual union all
 select 2 id, 'reg123'  str from dual union all
 select 3 id, 'xyddqd'  str from dual union all
 select 4 id, 'ffxyzf'  str from dual --union all
)
select id, str, chr(chr1) || chr(chr2) || chr(chr3)
from
   (select distinct id, str,
    ascii(substr(str, level, 1))   chr3,
    ascii(substr(str, level -1, 1))chr2,
    ascii(substr(str, level -2, 1))chr1
    from s connect by level <= length(str)
   ) 
where chr3 - 1 = chr2 and chr2 - 1 = chr1
order by id
19 июн 10, 19:42    [8968514]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
infantis,

with t as (select 'edcfthnjuj' a from dual
 union all select 'afbcd000'     from dual)
   ,t1 as (
  select chr(level)||chr(level+1)||chr(level+2) a3
         from dual
   connect by level < 254
 ),t2 as (select a3
                ,rownum r
            from t1
           where regexp_like(a3,'[[:alpha:]]{3}')
 ),t3 as (select sys_connect_by_path(a3,'|') ss
            from t2
      connect by r = prior r+1
      start with r = 1
 ),t4 as (select ltrim(max(ss),'|') mask from t3)
   select a
     from t
         ,t4
    where regexp_like(a,mask);
19 июн 10, 19:52    [8968525]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
AmKad
Member

Откуда:
Сообщений: 5222
infantis,

Без использования Distinct, но с учетом ограничения длины строки на 4000:
with s as
(select 1 id, 'abcfrf'  str from dual union all
 select 2 id, 'reg123'  str from dual union all
 select 3 id, 'xyddqd'  str from dual union all
 select 4 id, 'ffxyzf'  str from dual --union all
)
select s.id, s.str,    
    substr(str, lvl -2, 1)||
    substr(str, lvl -1, 1)||
    substr(str, lvl, 1)   sub_str
from s 
left join 
    (select level as lvl from dual connect by level <= 4000
    ) lvl on length(s.str) >= lvl.lvl
where ascii(substr(str, lvl.lvl, 1))    - 1 = ascii(substr(str, lvl.lvl -1, 1)) 
and   ascii(substr(str, lvl.lvl -1, 1)) - 1 = ascii(substr(str, lvl.lvl -2, 1))
order by s.id, s.str
19 июн 10, 20:02    [8968543]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
AmKad
Member

Откуда:
Сообщений: 5222
AmKad
infantis,

Без использования Distinct, но с учетом ограничения длины строки на 4000:
with s as
(select 1 id, 'abcfrf'  str from dual union all
 select 2 id, 'reg123'  str from dual union all
 select 3 id, 'xyddqd'  str from dual union all
 select 4 id, 'ffxyzf'  str from dual --union all
)
select s.id, s.str,    
    substr(str, lvl -2, 1)||
    substr(str, lvl -1, 1)||
    substr(str, lvl, 1)   sub_str
from s 
inner join 
    (select level as lvl from dual connect by level <= 4000
    ) lvl on length(s.str) >= lvl.lvl
where ascii(substr(str, lvl.lvl, 1))    - 1 = ascii(substr(str, lvl.lvl -1, 1)) 
and   ascii(substr(str, lvl.lvl -1, 1)) - 1 = ascii(substr(str, lvl.lvl -2, 1))
order by s.id, s.str

Это несколько понизит стоимость запроса.
19 июн 10, 20:06    [8968549]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
infantis
Member

Откуда: Санкт-Петербург
Сообщений: 4
orawish, AmKad
Спасибо, все работает. Я новичок, поэтому мне наиболее понятен первый вариант, но с остальными тоже попробую разобраться. :)
19 июн 10, 20:09    [8968554]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
AmKad
Member

Откуда:
Сообщений: 5222
infantis
orawish, AmKad
Спасибо, все работает. Я новичок, поэтому мне наиболее понятен первый вариант, но с остальными тоже попробую разобраться. :)

Говоря на простом языке, если верить Ораклу (а если точнее - то оптимизатору), вариант с inner join без Distinct-а ему обойдется дешевле, т.е. потребуется меньше ресурсов.
19 июн 10, 20:13    [8968566]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
infantis
orawish, AmKad
Спасибо, все работает. Я новичок, поэтому мне наиболее понятен первый вариант, но с остальными тоже попробую разобраться. :)

да не за что. это вам спасибо, за задачку. (сессия ? ;)

вот ещё
with t as (select 'edcfthnjuj' a from dual
 union all select 'afbcd000'     from dual
 )
 ,t2 as (select a
              ,regexp_substr(a,'[[:alpha:]]{3}',level) s
          from t
    connect by regexp_substr(a,'[[:alpha:]]{3}',level) is not null
           and a = prior a
           and prior dbms_random.value is not null
) select a, min(s) s
    from t2
   where ascii(substr(s,1,1))+1=ascii(substr(s,2,1))
     and ascii(substr(s,2,1))+1=ascii(substr(s,3,1))
group by a;
19 июн 10, 20:22    [8968588]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
infantis,

обратите внимание, что в разных решениях по-разному трактуется это:

infantis
.. буквы алфавита..
19 июн 10, 20:37    [8968615]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10050
If you are looking for case-insensitive search:

with t as (
           select 'edcfthnjuj'a from dual union all
           select 'afbcd000klm'    from dual union all
           select 'gfdhgabcgfs'    from dual union all
           select 'hds9f0-9xyz'    from dual
          )
  select  a,
          substr(a,column_value,3)
    from  t,
          table(cast(multiset(select level from dual connect by level <= length(a) - 2) as sys.OdciNumberList))
    where instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substr(upper(a),column_value,3)) > 0
/

A           SUB
----------- ---
afbcd000klm bcd
afbcd000klm klm
gfdhgabcgfs abc
hds9f0-9xyz xyz

SQL> 

SY.
19 июн 10, 21:44    [8968738]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
SY
If you are looking for case-insensitive search:

with t as (
           select 'edcfthnjuj'a from dual union all
           select 'afbcd000klm'    from dual union all
           select 'gfdhgabcgfs'    from dual union all
           select 'hds9f0-9xyz'    from dual
          )
  select  a,
          substr(a,column_value,3)
    from  t,
          table(cast(multiset(select level from dual connect by level <= length(a) - 2) as sys.OdciNumberList))
    where instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substr(upper(a),column_value,3)) > 0
/

A           SUB
----------- ---
afbcd000klm bcd
afbcd000klm klm
gfdhgabcgfs abc
hds9f0-9xyz xyz

SQL> 

SY.

Этот вариант наиболее правильный для не-латинских символов
А вообще решать влоб - слепить regexp для поиска одной из 24 подстрок. Ну, это для регистро-независимого. А для регистро-зависимого - оснастить вторым регекспом в виде аппера по первому.
Ну, чтоб быть кросавчегом, регексп слепить через коннектбай.
19 июн 10, 22:47    [8968850]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10050
RA\/EN
А для регистро-зависимого - оснастить вторым регекспом в виде аппера по первому.


Why? Just add lowercase letter sequence:

with t as (
           select 'edcfthnjuj'a from dual union all
           select 'afbcd000klm'    from dual union all
           select 'gfdhgabcgfs'    from dual union all
           select 'gfdhgABCgfs'    from dual union all
           select 'gfdhgaBcgfs'    from dual union all
           select 'hds9f0-9xyz'    from dual
          )
  select  a,
          substr(a,column_value,3)
    from  t,
          table(cast(multiset(select level from dual connect by level <= length(a) - 2) as sys.OdciNumberList))
    where instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substr(a,column_value,3)) > 0
       or instr('abcdefghijklmnopqrstuvwxyz',substr(a,column_value,3)) > 0
/

A           SUB
----------- ---
afbcd000klm bcd
afbcd000klm klm
gfdhgabcgfs abc
gfdhgABCgfs ABC
hds9f0-9xyz xyz

SQL> 

SY.

Сообщение было отредактировано: 19 июн 10, 23:00
19 июн 10, 22:59    [8968870]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
а по скорострельности, думаю, всех обставит решение на модельке.
и на длинных строках, существенно
19 июн 10, 23:36    [8968953]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
SY
RA\/EN
А для регистро-зависимого - оснастить вторым регекспом в виде аппера по первому.

Why? Just add lowercase letter sequence:

Да не совсем в этом дело... Просто коррелированная вьюха с картезианом напрягает... Правда, задача при моем видении сводится к регенрации регекспа, что, наверное, не есть то, что, возможно, хотел автор
А вообще, фиг его знает, что производительнее будет - большой регексп или инстр по алфавиту. В понедельник посмотрю или кого не заломает...
19 июн 10, 23:41    [8968971]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
orawish
а по скорострельности, думаю, всех обставит решение на модельке.
и на длинных строках, существенно

3998 итераций вычисления разницы между i и i+1 элементом, а потом substr(xxx,chr(1)||chr(1)||chr(1))? на больших - возможно, на 1 большой и 1е5 маленьких - думаю, и решение SY модельку сделает.
19 июн 10, 23:44    [8968981]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
RA\/EN
orawish
а по скорострельности, думаю, всех обставит решение на модельке.
и на длинных строках, существенно

3998 итераций вычисления разницы между i и i+1 элементом, а потом INSTR(xxx,chr(1)||chr(1)||chr(1))? на больших - возможно, на 1 большой и 1е5 маленьких - думаю, и решение SY модельку сделает.
19 июн 10, 23:44    [8968982]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
RA\/EN
RA\/EN
orawish
а по скорострельности, думаю, всех обставит решение на модельке.
и на длинных строках, существенно

3998 итераций вычисления разницы между i и i+1 элементом, а потом INSTR(xxx,chr(1)||chr(1)||chr(1))? на больших - возможно, на 1 большой и 1е5 маленьких - думаю, и решение SY модельку сделает.

ну вот - уже пошли ставки. :)
предлагаю в качестве теста
~10000 dbms_random.string A 1000
19 июн 10, 23:55    [8969012]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
Elic
Member

Откуда:
Сообщений: 29987
А ничего, что порядок букв в алфавите и порядок символов в любом варианте русской кодировки - вещи несопоставимые?
20 июн 10, 00:02    [8969025]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10050
Elic
А ничего, что порядок букв в алфавите и порядок символов в любом варианте русской кодировки - вещи несопоставимые?


That is why my suggestion uses collating sequence.

SY.
20 июн 10, 00:19    [8969053]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
а для одного набора латиницы, длины <4000/3 и 10r2+ окак можно:
with t as (select 'edcfthnjuj' s from dual
 union all select 'bcd000'       from dual
 )
 ,t0 as (select 'abcdefghijklmnopqrstuvwxyz' az from dual)
 ,t2 as (select --+ materialize
                s
               ,s||translate(s,substr(az,2)||'.',az)
                 ||translate(s,substr(az,3)||'..',az) s3
               ,'([a-z]{1}).{'||length(s)||'}\1.{'||length(s)||'}\1' mask
          from t,t0
) select *
    from t2
   where regexp_like(s3,mask);

правдп хинтец пришлось поставить - без него домашний 10.2.0.1 на винде ничего не ловил
20 июн 10, 00:54    [8969082]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
таки моделька
SQL> col st format a50
SQL> set timing on pages 0
SQL> with t1 as  (select dbms_random.string('a',100) as st
  2                 from dual connect by level <1001
  3    ) ,t as (
  4    select st,z,r from t1
  5    model
  6    partition by (st)
  7    dimension by (0 as z)
  8    measures ( st as s
  9              ,cast(null as varchar2(3)) as r )
 10    rules iterate(1)
 11    (
 12      r[for z from 1 to length(s[0])-2 increment 1] =
 13          case when regexp_like(substr(s[0],cv(z),1),'[[:alpha:]]')
 14                and ascii(substr(s[0],cv(z),1)) = ascii(substr(s[0],cv(z)+1,1))-1
 15                and ascii(substr(s[0],cv(z),1)) = ascii(substr(s[0],cv(z)+2,1))-2
 16               then substr(s[0],cv(z),3) end
 17    )
 18  )   select st,min(to_char(z,'9990')||' '||r) min_r
 19        from t
 20       where r is not null
 21    group by st;
xknxxsrsthbLpqmMdmxVUiCdiIBdMRDOjvciTxKwDoFHBzrTVO     7 rst
WQMvygsoaKKvGddEtIowJgaDdViuxEWXtZNCuckDsdsRahszQp

iHgnlLLuddnVZEyFUqXtOwvGEoebGkpdjVvpmfwwWyiuVzxmqq    78 stu
TPdDZnwLOsvAYNzjKMjvCqoFnjwstufyrjnORghKhigVKVhtHF

..

NiSVgHrGPgaPzHuvsCSksTPbxGxQZqvrxjSqiGuqRvKnylklmQ    47 klm
JjNSuKpPlGymyMQtFiOplJxdXrFzMjXGznIpCnzEwgttChoQVM


30 строк выбрано.

Затрач.время: 00:00:03.42
20 июн 10, 16:14    [8969733]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10050
orawish
таки моделька


Tаки нет. I removed group by from your solution to make it fair comparison:

SQL> select * from v$version
  2  /
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE    11.1.0.6.0      Production
TNS for 32-bit Windows: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production

SQL> create table t1 as
  2             select  dbms_random.string('a',100) st
  3               from  dual
  4               connect by level <1001
  5  /

Table created.

SQL> set linesize 132
SQL> col st format a100
SQL> set timing on pages 0
SQL> select  st,
  2          substr(st,column_value,3)
  3    from  t1,
  4          table(cast(multiset(select level from dual connect by level <= length(st) - 2) as sys.OdciNumberList))
  5    where instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substr(st,column_value,3)) > 0
  6       or instr('abcdefghijklmnopqrstuvwxyz',substr(st,column_value,3)) > 0
  7  /
IsaoPscKZrbQjVYETiTxiBcobPxFKrGUKslXnmSCqZslmnxlLXauONMkIXtZjiekkNnXIqGKHMiVpaZnnYzYESESQfxXVxmbmgIv lmn
ofCcOwovHnelKKqOdmwWJZGfNXggdEekMTAeflcdnaqRqvVKxfSOZiMCCjJrBSgTGfPqvTsRMmozVbqLCyvCnqmOCKVhEIxtFGHm FGH
aDVICDueizIrIDyrEBGiPtbTSvccOgwWzHxWXtBxFnopDcPgTUbzzahsyykQjrBhHGOfwzoJpuYSVqzlPDcOGePxGinHkCeNuCVz nop
XrUXePLRxaTldHOiONNDqCwpmmzyzHrKiTbYvHNLmdNESiRqXKZzfghKeTVeXDbgtvJYOctBqbHJlNfKwZxfoYUMmwCSKpsgYWdh fgh
YKaaNZgMjoqmHBSbemEyiIOsLxkJRtsmSYbTjqbeNlqHzZUyaCaIzDVkILkeSYyCMSFrstFsXvFiijrmALSQwNWajLxCPZhaDwys rst
vKiEXooHOwJaEmmyYsBgOEFVgrVdwTVDyblGBnaeVqxDSlVgBDVgEEecBDhTHKLMYugFZMctiykgpbBivqKBXzfzfTaIxlruleJr KLM
OgiLxpAvJZeOuHBApXPPiKqYvAHHIJUkjguUxfNDnLcausbrdLGQEkjKhqTFzVfsGZjsmPEdispdDSQZLOYMtEvQXOawBtwtkMTh HIJ
ZfTALhcYDjvKPKhPDfENMAcgCOwLqLDLQHBrGiSICFuoElCMyzOiQRSbtPLBtgkTrwCVtzXFkzCRletBOKtHdWnJXNtAOCcuCwKy QRS
UdTCXLEdnHNVvMwYqxxHPDaQiRqYQHVHRsnSsRtagcNGtbhAfLjqbcdDuJboSalFABondpyWZLNIeHROdaOrkyLMCOGLrefgdCuX bcd
UdTCXLEdnHNVvMwYqxxHPDaQiRqYQHVHRsnSsRtagcNGtbhAfLjqbcdDuJboSalFABondpyWZLNIeHROdaOrkyLMCOGLrefgdCuX efg
etCXseVtILhlIDBFzqYustutgIWslyojxCxDPXRJDmzrMZGxRFZYOWnKCYQddKcFOepXaSPCcXmETBrxOvRzUctzbNhshtPSRoPm stu
DvZvOcGsDhdlYaPQRHEVIfqXFqLhlbPSDZfPHvpQrgXTMkUBeFNUTXxJlkdzEVLHHJAgVFhIocoUPKYkvYCEyNcpKIPMRAXzqYAh PQR
HbLuemtXdJvhDdDBmFPURkKBPsxLjkBGqhKlVNSNijkigLaZmwsuKsyWTJGNWveTrGTZrWOUpACywkbCoqGtcAdJqQzsIwhZpDIY ijk
cIpYGWsZlRejEvCafuxzLrTsRjoYyeyiTGcZxxrTtcYBtbQLQBuExhXtrdwEBrIFXGJBstuZXWAETjEhkicwLVcLjZeyoAZRjiCm stu
hCEsJkchTRGTNjThOqnrxtTUVXwNNWEoqJTVBFAETgYKlnGrKkAPwuaDZBGXHhVJbZpPoUmhXLBjgaMfHxdKRfrPLZsJmWOuFOZa TUV
YuRHBKpVvbEMJehRvFfAABCiMtJCryOoptFaDVwgswRwoXfqrxvAHEAknbJtJDKlVJnNAdyoBwwoZiZDqECzCOZdUPTMZGSOFEJo ABC
KLEOjQvqKZMcwgxGcjFHYYlLVmkJuzYygRdwGQMvmIXsNZXHkdffRfWgxoXdQTpqrpZCwKBPrcAlxJSGPPpLfvedGBaWkBldywvJ pqr
BNKKqCkQBjeJsMpnkniTsndVARefgYWRrIQFOXaHXHDGhDKtpeLLdajCfoqWbHhssvPGjPuIvlaaqoOqwqrJyFTXxHcqeIzQCSNR efg
SFCkPmmUOysbehgaNBPpCrwOXuYxDorJuRaMcdeNDLyboIQsJPFFJKgqAaiTadeJPSnHLKoRNORrzNGhKdDNyXAurJfCGJWTemjA cde
RxrQbYmmDpasFekTzvwxemNnhtnhtzUrrZwHnxWsbOcPpkxRghlUIlHyrfxUXGevPWAscGMaJZMTXLFNbZBCkbqiFtcKEAnqkdIR vwx
XJMrHawXjPhvFiDQJkOhpCcnhxxZbNEpGmjcmSwOweJWoZOKLkpZGAEFGKQjnBMqCQYsBzeFOYEdcrxshmyiNJuNwALaUJEyuiOp EFG
uvisdmhjelDyPPtyDQDZgCzivyVCTxYYzkuvwZvKrAtgeDTSgWGiKelqtEvxjFIdWxtLppJvRxFKGTBcUclecJPtpqsffEoOymsT uvw
czxSBcigcWCRQvqFGkomnoCovAKQinaALxoFeBkXIpUJbIWsRMcYBjUXzIikQJgnUrXuxbcOaIvOxZhNNnojXuYLGXquLRLcgrEY mno
bjLxSuXajOCnNDqvpUOgVIhYxaanzkyckQXzWEfkrNFFczlITuVhAZGZJllSeVCTfamjIVghiUlyITgRUvVzJEBtCISAaiEXnsok ghi
kNtzTEooLlVjGgNSEJysiGxVlYqUYVipllfTjXlRyEFZJKLELCCHlJEVmkTsZWexXBDpDykDNERrRJZwbscKfmLXWzLJuPPWGION JKL
QmHvQFGHFZofjkaIumqaJtJLliDAZuVmFOckZpMFRwvVCCKKLYLqxPDBULwpzctLnRPIanNLjlvLwTVxGPrWJYoaZZZZRGQENKdd FGH
tZUfjbthYQNmlVTMCcDqthVtfWpghSiSGsYbMoLwVHfLLVtXCNUbjzlZvKLQuczfJmOxJfIXjjBEDPRikKIRSTrCCksHRKbeuuIU RST
dspxZncDMdRslpvKWhZASQqPcEinylUGIqeswnjvugFmKTugsgxhbJzGwYkXZxKVUwlhcfGQOenckkvVkgUavUMEOPQVktROdqUn OPQ
whVSZVIBLhhOWduWWyqNmaNscWskWOsreVKMSubfUSRhVeuEnDSpwYgZDNDwjBtqCsapYWCrQIuHFIwQZLaTnZRhiNICvUVWKsWt UVW
pVSrUUdefnOHZhIRAkzrXHqDkzUXwtxDkzKJcnNzHXbRatyeiNzQcTQaUmPRNahPmYRCVVRHHbJyAphSMUoZMOeElZbqOvPtvtUv def
KqYrhPlRrTNbOfPgsJpKNsfLucpAuLDOIgzqiQeFDuPwzVxFbRUIChdESNscapfzzNSwvumwEFGNOcRVtJJxshSbtsSIFKFDIhtv EFG
hSsrtZtLkauWseCQrkGLMjAEKzbBFJhTwhOFpUDHhedBmvjxOObuvwmrRUszjaegHIbhzGXZOjMyekBYNDvBFTLOBGEYvinpnEim uvw
cvjOHbNZETKfIOTJbEikiJolMqdCPPItRydRhvhNvWphNZMJGtDymmnolMQXqVTWSnxqJAWWaXSvjBuTjhBCCviDLuoYQAjNJmYW mno
NdykCcOotHTsLvxQogegmplQjpWRntHdZMQmpBVPlcFFyBFszebrgktwSVBpVVRSTkfBxTfZJklkqrIiTxIUdAZshScKXniENkGv RST

34 rows selected.

Elapsed: 00:00:00.28
SQL> with t as (
  2    select st,z,r from t1
  3    model
  4    partition by (st)
  5    dimension by (0 as z)
  6    measures ( st as s
  7              ,cast(null as varchar2(3)) as r )
  8    rules iterate(1)
  9    (
 10      r[for z from 1 to length(s[0])-2 increment 1] =
 11          case when regexp_like(substr(s[0],cv(z),1),'[[:alpha:]]')
 12                and ascii(substr(s[0],cv(z),1)) = ascii(substr(s[0],cv(z)+1,1))-1
 13                and ascii(substr(s[0],cv(z),1)) = ascii(substr(s[0],cv(z)+2,1))-2
 14               then substr(s[0],cv(z),3) end
 15    )
 16  )   select st,r
 17        from t
 18       where r is not null
 19  /
XJMrHawXjPhvFiDQJkOhpCcnhxxZbNEpGmjcmSwOweJWoZOKLkpZGAEFGKQjnBMqCQYsBzeFOYEdcrxshmyiNJuNwALaUJEyuiOp EFG
RxrQbYmmDpasFekTzvwxemNnhtnhtzUrrZwHnxWsbOcPpkxRghlUIlHyrfxUXGevPWAscGMaJZMTXLFNbZBCkbqiFtcKEAnqkdIR vwx
aDVICDueizIrIDyrEBGiPtbTSvccOgwWzHxWXtBxFnopDcPgTUbzzahsyykQjrBhHGOfwzoJpuYSVqzlPDcOGePxGinHkCeNuCVz nop
cIpYGWsZlRejEvCafuxzLrTsRjoYyeyiTGcZxxrTtcYBtbQLQBuExhXtrdwEBrIFXGJBstuZXWAETjEhkicwLVcLjZeyoAZRjiCm stu
dspxZncDMdRslpvKWhZASQqPcEinylUGIqeswnjvugFmKTugsgxhbJzGwYkXZxKVUwlhcfGQOenckkvVkgUavUMEOPQVktROdqUn OPQ
kNtzTEooLlVjGgNSEJysiGxVlYqUYVipllfTjXlRyEFZJKLELCCHlJEVmkTsZWexXBDpDykDNERrRJZwbscKfmLXWzLJuPPWGION JKL
hSsrtZtLkauWseCQrkGLMjAEKzbBFJhTwhOFpUDHhedBmvjxOObuvwmrRUszjaegHIbhzGXZOjMyekBYNDvBFTLOBGEYvinpnEim uvw
uvisdmhjelDyPPtyDQDZgCzivyVCTxYYzkuvwZvKrAtgeDTSgWGiKelqtEvxjFIdWxtLppJvRxFKGTBcUclecJPtpqsffEoOymsT uvw
QmHvQFGHFZofjkaIumqaJtJLliDAZuVmFOckZpMFRwvVCCKKLYLqxPDBULwpzctLnRPIanNLjlvLwTVxGPrWJYoaZZZZRGQENKdd FGH
IsaoPscKZrbQjVYETiTxiBcobPxFKrGUKslXnmSCqZslmnxlLXauONMkIXtZjiekkNnXIqGKHMiVpaZnnYzYESESQfxXVxmbmgIv lmn
KLEOjQvqKZMcwgxGcjFHYYlLVmkJuzYygRdwGQMvmIXsNZXHkdffRfWgxoXdQTpqrpZCwKBPrcAlxJSGPPpLfvedGBaWkBldywvJ pqr
YuRHBKpVvbEMJehRvFfAABCiMtJCryOoptFaDVwgswRwoXfqrxvAHEAknbJtJDKlVJnNAdyoBwwoZiZDqECzCOZdUPTMZGSOFEJo ABC
czxSBcigcWCRQvqFGkomnoCovAKQinaALxoFeBkXIpUJbIWsRMcYBjUXzIikQJgnUrXuxbcOaIvOxZhNNnojXuYLGXquLRLcgrEY mno
bjLxSuXajOCnNDqvpUOgVIhYxaanzkyckQXzWEfkrNFFczlITuVhAZGZJllSeVCTfamjIVghiUlyITgRUvVzJEBtCISAaiEXnsok ghi
XrUXePLRxaTldHOiONNDqCwpmmzyzHrKiTbYvHNLmdNESiRqXKZzfghKeTVeXDbgtvJYOctBqbHJlNfKwZxfoYUMmwCSKpsgYWdh fgh
OgiLxpAvJZeOuHBApXPPiKqYvAHHIJUkjguUxfNDnLcausbrdLGQEkjKhqTFzVfsGZjsmPEdispdDSQZLOYMtEvQXOawBtwtkMTh HIJ
tZUfjbthYQNmlVTMCcDqthVtfWpghSiSGsYbMoLwVHfLLVtXCNUbjzlZvKLQuczfJmOxJfIXjjBEDPRikKIRSTrCCksHRKbeuuIU RST
hCEsJkchTRGTNjThOqnrxtTUVXwNNWEoqJTVBFAETgYKlnGrKkAPwuaDZBGXHhVJbZpPoUmhXLBjgaMfHxdKRfrPLZsJmWOuFOZa TUV
pVSrUUdefnOHZhIRAkzrXHqDkzUXwtxDkzKJcnNzHXbRatyeiNzQcTQaUmPRNahPmYRCVVRHHbJyAphSMUoZMOeElZbqOvPtvtUv def
SFCkPmmUOysbehgaNBPpCrwOXuYxDorJuRaMcdeNDLyboIQsJPFFJKgqAaiTadeJPSnHLKoRNORrzNGhKdDNyXAurJfCGJWTemjA cde
KqYrhPlRrTNbOfPgsJpKNsfLucpAuLDOIgzqiQeFDuPwzVxFbRUIChdESNscapfzzNSwvumwEFGNOcRVtJJxshSbtsSIFKFDIhtv EFG
whVSZVIBLhhOWduWWyqNmaNscWskWOsreVKMSubfUSRhVeuEnDSpwYgZDNDwjBtqCsapYWCrQIuHFIwQZLaTnZRhiNICvUVWKsWt UVW
etCXseVtILhlIDBFzqYustutgIWslyojxCxDPXRJDmzrMZGxRFZYOWnKCYQddKcFOepXaSPCcXmETBrxOvRzUctzbNhshtPSRoPm stu
NdykCcOotHTsLvxQogegmplQjpWRntHdZMQmpBVPlcFFyBFszebrgktwSVBpVVRSTkfBxTfZJklkqrIiTxIUdAZshScKXniENkGv RST
ZfTALhcYDjvKPKhPDfENMAcgCOwLqLDLQHBrGiSICFuoElCMyzOiQRSbtPLBtgkTrwCVtzXFkzCRletBOKtHdWnJXNtAOCcuCwKy QRS
ofCcOwovHnelKKqOdmwWJZGfNXggdEekMTAeflcdnaqRqvVKxfSOZiMCCjJrBSgTGfPqvTsRMmozVbqLCyvCnqmOCKVhEIxtFGHm FGH
BNKKqCkQBjeJsMpnkniTsndVARefgYWRrIQFOXaHXHDGhDKtpeLLdajCfoqWbHhssvPGjPuIvlaaqoOqwqrJyFTXxHcqeIzQCSNR efg
DvZvOcGsDhdlYaPQRHEVIfqXFqLhlbPSDZfPHvpQrgXTMkUBeFNUTXxJlkdzEVLHHJAgVFhIocoUPKYkvYCEyNcpKIPMRAXzqYAh PQR
HbLuemtXdJvhDdDBmFPURkKBPsxLjkBGqhKlVNSNijkigLaZmwsuKsyWTJGNWveTrGTZrWOUpACywkbCoqGtcAdJqQzsIwhZpDIY ijk
YKaaNZgMjoqmHBSbemEyiIOsLxkJRtsmSYbTjqbeNlqHzZUyaCaIzDVkILkeSYyCMSFrstFsXvFiijrmALSQwNWajLxCPZhaDwys rst
UdTCXLEdnHNVvMwYqxxHPDaQiRqYQHVHRsnSsRtagcNGtbhAfLjqbcdDuJboSalFABondpyWZLNIeHROdaOrkyLMCOGLrefgdCuX bcd
UdTCXLEdnHNVvMwYqxxHPDaQiRqYQHVHRsnSsRtagcNGtbhAfLjqbcdDuJboSalFABondpyWZLNIeHROdaOrkyLMCOGLrefgdCuX efg
cvjOHbNZETKfIOTJbEikiJolMqdCPPItRydRhvhNvWphNZMJGtDymmnolMQXqVTWSnxqJAWWaXSvjBuTjhBCCviDLuoYQAjNJmYW mno
vKiEXooHOwJaEmmyYsBgOEFVgrVdwTVDyblGBnaeVqxDSlVgBDVgEEecBDhTHKLMYugFZMctiykgpbBivqKBXzfzfTaIxlruleJr KLM

34 rows selected.

Elapsed: 00:00:01.64
SQL> 

SY.
20 июн 10, 16:46    [8969772]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
SY,

ну, нет так нет :)
вот еще модель - на тему, которую RA\/EN озвучил.
тут получается на ~четверть быстрее, чем предыдущая модель
(и то, только за счет финта пытаться шагать по 2)

col st format a50
set timing on pages 0
with t1 as  (select dbms_random.string('a',100) as st
               from dual connect by level <1001
  ) ,t as (
  select * from t1
  model
  partition by (st)
  dimension by (0 as z)
  measures ( st as s
            ,cast(null as varchar2(3)) as r 
            ,1 as i
            ,0 as n
           )
  rules iterate(100) 
  until (r[0] is not null or i[0] >= length(s[0])-2)
  (
    n[0] = case when ascii(substr(s[0],i[0]+1,1)) = ascii(substr(s[0],i[0]+2,1))-1
                then 0 end
   ,n[0] = case when n[0] is null then 2
                when n[0] = 0
                 and ascii(substr(s[0],i[0]  ,1)) = ascii(substr(s[0],i[0]+1,1))-1
                then 0 else 1 end
   ,r[0] = case when n[0] = 0 then substr(s[0],i[0],3) end
   ,i[0] = i[0]+n[0]
  )
)   select s,r,i 
      from t
     where r is not null;
20 июн 10, 19:05    [8969997]     Ответить | Цитировать Сообщить модератору
 Re: поиск трех подряд идущих букв алфавита  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
SY
orawish
таки моделька


Tаки нет. I removed group by from your solution to make it fair comparison:
...
SY.

Догоним и перегоним!
SQL> set timing on
SQL> -- решение SY: все вхождения трех символов
SQL> select  COUNT(st)
  2    from  t1,
  3          table(cast(multiset(select level from dual connect by level <= length(st) - 2) as sys.OdciNumberList))
  4    where instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substr(st,column_value,3)) > 0
  5       or instr('abcdefghijklmnopqrstuvwxyz',substr(st,column_value,3)) > 0
  6  /
 
 COUNT(ST)
----------
       340
 
Executed in 2,313 seconds

SQL> -- А зачем нам instr, если можно join? :)
SQL> SELECT COUNT(q.st||q.ss)--q.st,q.ss
  2    FROM (select  st,
  3                  substr(t1.st,x.column_value,3) SS
  4            from  (SELECT * FROM t1 ) t1,
  5                  table(cast(multiset(select level from dual connect by level <= length(st) - 2) as sys.OdciNumberList)) x) q,
  6         (select  substr(s,column_value,3) pt
  7            from  (SELECT 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' s FROM dual
  8                    UNION ALL
  9                   SELECT 'abcdefghijklmnopqrstuvwxyz' s FROM dual) d,
 10                  table(cast(multiset(select level from dual connect by level <= length(s) - 2) as sys.OdciNumberList))
 11           GROUP BY substr(s,column_value,3)) t -- GROUP BY здесь "изящно" подпирает план
 12   WHERE q.ss=t.pt
 13  /
 
COUNT(Q.ST||Q.SS)--Q.ST,Q.SS
----------------------------
                         340
 
Executed in 1,562 seconds
23 июн 10, 12:07    [8986042]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить