powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подсчет количества уникальных значений в строке
36 сообщений из 36, показаны все 2 страниц
подсчет количества уникальных значений в строке
    #39850919
abort
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть строка 2222224444466
нужно вывести
1) используемых символов: 2,4,6
2) кол-во уникальных: 3
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39850923
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
with s as (select '2222224444466' str from dual)
select distinct substr(str, level, 1) c
from s
connect by level <= length(str);
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39850990
MirnyiAtom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
2.
3.
4.
5.
with s as (select '2222224444466' str from dual)
select distinct substr(str, level, 1) symb, count(substr(str, level, 1)) over(partition by substr(str, level, 1)) co
       ,count(distinct substr(str, level, 1)) over(partition by str) u_sum
from s
connect by level <= length(str);
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851022
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MirnyiAtom,

Сейчас придет Elic и будет ругать тебя за группировку через distinct с аналитикой. 👻
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851064
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
abortЕсть строка 2222224444466
Код: plsql
1.
2.
3.
4.
5.
SQL> select regexp_replace('2222224444466', '(.)\1+', '\1') from dual;

REG
---
246

...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851071
abort
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

вот! Ждал именно от этого метода regexp_replace. Но не смог выжать.
Всем спасибо за правильные ответы!
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851087
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
abortвот! Ждал именно от этого метода regexp_replace. Но не смог выжать.Ты понимаешь магию исходных данных?
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851094
Фотография mRdUKE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
abortвот! Ждал именно от этого метода regexp_replace. Но не смог выжать.При условии, что сортировка внутри строки сохранится (посимвольная).
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851097
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mRdUKEabortвот! Ждал именно от этого метода regexp_replace. Но не смог выжать.При условии, что сортировка внутри строки сохранится (посимвольная).

сначала '222222444446622244440' отсортировать, потом посчитать

....
stax
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851102
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
abort,
зачем тебе тут sql? решай через pl\sql и проще и на магию можно не полагаться)
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851103
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На малом словаре и длинных строках эффективнее этот словарь джоинить на строку.
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851122
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
with q (val) as (select '2a42w776242224444466' from dual)

select regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1') as "Используемые символы"
, length(regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1')||',')/2 as "Кол-во уникальных"
from q
connect by substr(val,level,1) is not null
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851140
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
интересно, есть ли вариант быстрее, чем PL/SQL функция?

на моем тестовом наборе она оказалась быстрее:
тестовые данные
Код: plsql
1.
2.
3.
create table t_str as
select round(dbms_random.value(1e10,9e10)) str from dual connect by level<=1e5
/

PL/SQL вариант
Код: 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.
with
  function ff(s varchar2) return varchar2 
  as
      type avarchars is table of varchar2(100) index by varchar2(1);
      st  avarchars;
      idx varchar2(1);
      res varchar2(10);
      
      function iterate( idx in out nocopy varchar2, arr in out nocopy avarchars) 
         return boolean
      as --pragma inline;
      begin
         if idx is null
            then idx:=arr.first; 
            else idx:=arr.next(idx);
         end if;
         return idx is not null;
      end;  
   begin
     for i in 1..length(s) loop
        st(substr(s,i,1)):=1;
     end loop;
     while iterate(idx,st) loop
        res:=res||idx;
     end loop;
     return res;
   end;

select min(ff(str)) res
from t_str
/

SQL вариант
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select min(fstr)
from t_str t
     cross apply (
     select listagg(c) within group (order by 1) fstr
     from (select
            distinct substr(t.str, level, 1) c
           from dual
           connect by level <= length(t.str)
          )
     )
/



с таймингом
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
SQL> create table t_str as
  2  select round(dbms_random.value(1e10,9e10)) str from dual connect by level<=1e5
  3  /

Table created.

Elapsed: 00:00:00.55
SQL> with
  2    function ff(s varchar2) return varchar2
  3    as
  4        type avarchars is table of varchar2(100) index by varchar2(1);
  5        st  avarchars;
  6        idx varchar2(1);
  7        res varchar2(10);
  8
  9        function iterate( idx in out nocopy varchar2, arr in out nocopy avarchars)
 10           return boolean
 11        as --pragma inline;
 12        begin
 13           if idx is null
 14              then idx:=arr.first;
 15              else idx:=arr.next(idx);
 16           end if;
 17           return idx is not null;
 18        end;
 19     begin
 20       for i in 1..length(s) loop
 21          st(substr(s,i,1)):=1;
 22       end loop;
 23       while iterate(idx,st) loop
 24          res:=res||idx;
 25       end loop;
 26       return res;
 27     end;
 28
 29  select min(ff(str)) res
 30  from t_str
 31  /

RES
--------------------------------------------------------------
0123

Elapsed: 00:00:00.48
SQL> select min(fstr) res2
  2  from t_str t
  3       cross apply (
  4       select listagg(c) within group (order by 1) fstr
  5       from (select
  6              distinct substr(t.str, level, 1) c
  7             from dual
  8             connect by level <= length(t.str)
  9            )
 10       )
 11  /

RES2
--------------------------------------------------------------
0123

Elapsed: 00:00:01.01

...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851145
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
конечно, если ограничиться только цифрами, то translate получится проще и быстрее всего:
Код: plsql
1.
2.
select min(translate('0123456789', translate('z0123456789','z'||str,'z'), chr(0)))
from t_str
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851147
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,
мне кажется ты на вызове функции и ифах теряешь.
может вместо:
Код: plsql
1.
2.
3.
while iterate(idx,st) loop
        res:=res||idx;
     end loop;


попробовать
Код: plsql
1.
2.
3.
for idx in st.first..st.last loop
 res:=res||idx;
end loop;


ну и если быть совсем честным, то надо убрать еще неявное преобразование
Код: plsql
1.
2.
3.
type avarchars is table of varchar2(100) index by varchar2(1);
заменив на 
type avarchars is table of number index by varchar2(1);


сорри. в этой подсети нет оракла, а на сайт лезть влом. :)
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851152
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Vint
Код: plsql
1.
st.first..st.last

смотри внимательно: это ассоциативный массив, в котором в ключах хранятся символы из строки.
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851154
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Vintну и если быть совсем честным, то надо убрать еще неявное преобразованиеособой разницы не будет, но проще, конечно, изменить на varchar2(1) а в приравнивании сделать null вместо 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.
30.
31.
with
  function ff(s varchar2) return varchar2 
  as
      type avarchars is table of varchar2(1) index by varchar2(1);
      st  avarchars;
      idx varchar2(1);
      res varchar2(10);
      
      function iterate( idx in out nocopy varchar2, arr in out nocopy avarchars) 
         return boolean
      as --pragma inline;
      begin
         if idx is null
            then idx:=arr.first; 
            else idx:=arr.next(idx);
         end if;
         return idx is not null;
      end;  
   begin
     for i in 1..length(s) loop
        st(substr(s,i,1)):=null;
     end loop;
     while iterate(idx,st) loop
        res:=res||idx;
     end loop;
     return res;
   end;

select min(ff(str)) res
from t_str
/

...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851155
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dshedoo,

я неуверен что поведение order by null не зависит от версии
раньше заблуждался, считая что order by null не будет сортировать

имхо, луче явно указывать поле сортировки

.....
stax
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851169
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Согласен, лучше всегда всё указывать явно.

Но в данном случае, нам же без разницы по какому полю будет сортировка, главное, чтобы оно было одинаковым для всех partition by val.
А если я правильно понимаю, то order by null на разных версиях будет всегда однороден для всех записей?
Никаких же рандомов и прочего?
Я почему-то считал, что order by null = order by null'овое поле.
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851172
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DshedooЯ почему-то считал, что order by null = order by null'овое поле.Именно поэтому ничего не гарантирует.
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851192
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DshedooStax,

Согласен, лучше всегда всё указывать явно.

Но в данном случае, нам же без разницы по какому полю будет сортировка, главное, чтобы оно было одинаковым для всех partition by val.
А если я правильно понимаю, то order by null на разных версиях будет всегда однороден для всех записей?
Никаких же рандомов и прочего?
Я почему-то считал, что order by null = order by null'овое поле.

мож я неправильно понял Вашу регулярку
если листагг не отсортирует, то не отработает и regexp_replace

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
  1  with q (val) as (select '2a42w776242224444466' from dual)
  2  select
  3  regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1') as "Используемые символы"
  4  , length(regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1')||',')/2 as "Кол-во уникальных"
  5  ,regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by level),'([^,]+)(,\1)+', '\1') as "Без сортіровки"
  6  from q
  7* connect by substr(val,level,1) is not null
SQL> /

Используемые символы
--------------------------------------------------------------------------------
Кол-во уникальных
-----------------
Без сортіровки
--------------------------------------------------------------------------------
2,4,6,7,a,w
                6
2,a,4,2,w,7,6,2,4,2,4,6



к стати на апексе
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with q (val) as (select '2a42w776242224444466' from dual)
select
regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1') as "Используемые"
, length(regexp_replace(listagg(substr(val,level,1),',') WITHIN GROUP (order by null),'([^,]+)(,\1)+', '\1')||',')/2 as "Кол-во"
from q
connect by substr(val,level,1) is not null
/
Используемые	Кол-во
2,a,4,2,w,7,6,2,4,2,4,6	12
1 rows returned in 0.00 seconds	        	Download



ps
в новых версиях distinct добавили в listagg, тогда и регулярки не надо

.....
stax
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851219
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderконечно, если ограничиться только цифрами, то translate получится проще и быстрее всего:
Код: plsql
1.
2.
select min(translate('0123456789', translate('z0123456789','z'||str,'z'), chr(0)))
from t_str

супер
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851248
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
Код: plsql
1.
2.
select min(translate('0123456789', translate('z0123456789','z'||str,'z'), chr(0)))
from t_str


Не будем останавливаться на пол-дороги :)
Код: plsql
1.
translate('0123456789', translate(chr(0)||'0123456789',chr(0)||str,chr(0)), chr(0))
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851254
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
andrey_anonymous,

не в ту сторону ты двинулся :) надо было вместо chr(0) последнего просто 'z' воткнуть - так намного короче
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851256
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,
сорри, не доглядел. вот что значит пара месяцев без единой строчки кода)
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851273
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
нашел еще один вариант, который быстрее, чем connect by:
Код: plsql
1.
2.
3.
4.
select *
from xmltable('fn:min(ora:view("XTENDER","T_STR")/ROW/STR/fn:codepoints-to-string(distinct-values(string-to-codepoints(xs:string(./text())))))'
     columns xx varchar2(10) path '.'
     )



Только вот баг там у оракла: в distinct-values какой-то отчаянный баг и на множестве строк начинает выдавать одни и те же данные.
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851276
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderначинает выдавать одни и те же данные.
По описанию - вероятно, кэш какой-то. Быть может, можно отключить...
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851279
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
andrey_anonymous,

да, фиксится, не успел ответить - ваял тест-кейс красивый :) как почти все XML баги, фиксится с помощью NO_XML_QUERY_REWRITE

тест кейс, показывающий, что на 1-2 строках нет бага
Код: 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.
33.
34.
35.
36.
--drop table t_str_1 purge;
--drop table t_str_2 purge;
--drop table t_str_10 purge;
create table t_str_1 as
select to_char(round(dbms_random.value(1e10,9e10)),'fm00000000000') str from dual connect by level<=1
/
create table t_str_2 as
select to_char(round(dbms_random.value(1e10,9e10)),'fm00000000000') str from dual connect by level<=2
/
create table t_str_10 as
select to_char(round(dbms_random.value(1e10,9e10)),'fm00000000000') str from dual connect by level<=10
/
select 
     (select count(*)     from t_str_1) cnt, 
     (select min(ff(str)) from t_str_1) str, 
     res
from xmltable('fn:min(ora:view("XTENDER","T_STR_1")/ROW/STR/fn:codepoints-to-string(distinct-values(string-to-codepoints(xs:string(./text())))))'
     columns res varchar2(10) path '.'
     )
union all
select
     (select count(*)     from t_str_2) cnt, 
     (select min(ff(str)) from t_str_2) str, 
     res
from xmltable('fn:min(ora:view("XTENDER","T_STR_2")/ROW/STR/fn:codepoints-to-string(distinct-values(string-to-codepoints(xs:string(./text())))))'
     columns res varchar2(10) path '.'
     )
union all
select
     (select count(*)     from t_str_10) cnt, 
     (select min(ff(str)) from t_str_10) str, 
     res
from xmltable('fn:min(ora:view("XTENDER","T_STR_10")/ROW/STR/fn:codepoints-to-string(distinct-values(string-to-codepoints(xs:string(./text())))))'
     columns res varchar2(10) path '.'
     )
/


результат
Код: plsql
1.
2.
3.
4.
5.
6.
7.
       CNT STR          RES
---------- ------------ ----------
         1 123457       123457
         2 0123689      0123689
        10 012345678    0568

3 rows selected.



пример фикса:
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
SQL> select * from t_str_10;

STR
------------
55550088506
11455429508
71400096720
38283778061
89880445061
36118993026
89292128423
86133782405
45576175643
56556141220

10 rows selected.

SQL> select *
  2  from xmltable('(ora:view("XTENDER","T_STR_10")/ROW[last()]/STR/fn:codepoints-to-string(for $u in distinct-values(string-to-codepoints(xs:string(./text()))) order by $u return $u))'
  3       columns
  4          res varchar2(10) path '.'
  5       )
  6  /

RES
----------
0568
0568
0568
0568
0568
0568
0568
0568
0568
0568

10 rows selected.

SQL> select/*+ NO_XML_QUERY_REWRITE */ *
  2  from xmltable('(ora:view("XTENDER","T_STR_10")/ROW[last()]/STR/fn:codepoints-to-string(for $u in distinct-values(string-to-codepoints(xs:string(./text()))) order by $u return $u))'
  3       columns
  4          res varchar2(10) path '.'
  5       )
  6  /

RES
----------
0568
0124589
0124679
0123678
0145689
0123689
123489
012345678
134567
012456

10 rows selected.

...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851422
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderинтересно, есть ли вариант быстрее, чем PL/SQL функция?

на моем тестовом наборе она оказалась быстрее:


instr не побыстрее колекций будет?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with 
  function ff(s varchar2) return varchar2 
  as
      idx varchar2(1);
      res varchar2(100);
      l pls_integer;
   begin
     if s is null then return null;end if;
     res:=substr(s,1,1);
     l:=length(s);
     for i in 2..l loop
        idx:=substr(s,i,1);
        if instr(res,idx)=0 then
          res:=res||idx;
        end if;
     end loop;
     return res;
   end;
select min(ff(str)) res
from (select '1111z111112222zzz111z' str from dual) t_str
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851426
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Staxxtenderинтересно, есть ли вариант быстрее, чем PL/SQL функция?

на моем тестовом наборе она оказалась быстрее:


instr не побыстрее колекций будет?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with 
  function ff(s varchar2) return varchar2 
  as
      idx varchar2(1);
      res varchar2(100);
      l pls_integer;
   begin
     if s is null then return null;end if;
     res:=substr(s,1,1);
     l:=length(s);
     for i in 2..l loop
        idx:=substr(s,i,1);
        if instr(res,idx)=0 then
          res:=res||idx;
        end if;
     end loop;
     return res;
   end;
select min(ff(str)) res
from (select '1111z111112222zzz111z' str from dual) t_str

так чуть быстрее

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE OR REPLACE FUNCTION ff1 (s VARCHAR2)
    RETURN VARCHAR2
AS
    v_res   VARCHAR2 (100) := NULL;
    v_s     VARCHAR2 (4000) := s;
BEGIN
    WHILE v_s IS NOT NULL
    LOOP
        v_res := v_res || SUBSTR (v_s, 1, 1);
        v_s := REPLACE (v_s, SUBSTR (v_s, 1, 1));
    END LOOP;

    RETURN v_res;
END;
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851430
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxStaxпропущено...


instr не побыстрее колекций будет?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with 
  function ff(s varchar2) return varchar2 
  as
      idx varchar2(1);
      res varchar2(100);
      l pls_integer;
   begin
     if s is null then return null;end if;
     res:=substr(s,1,1);
     l:=length(s);
     for i in 2..l loop
        idx:=substr(s,i,1);
        if instr(res,idx)=0 then
          res:=res||idx;
        end if;
     end loop;
     return res;
   end;
select min(ff(str)) res
from (select '1111z111112222zzz111z' str from dual) t_str


так чуть быстрее

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE OR REPLACE FUNCTION ff1 (s VARCHAR2)
    RETURN VARCHAR2
AS
    v_res   VARCHAR2 (100) := NULL;
    v_s     VARCHAR2 (4000) := s;
BEGIN
    WHILE v_s IS NOT NULL
    LOOP
        v_res := v_res || SUBSTR (v_s, 1, 1);
        v_s := REPLACE (v_s, SUBSTR (v_s, 1, 1));
    END LOOP;

    RETURN v_res;
END;

если есть/нет повторяющихся символов, то результаты меняются
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851562
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
andreymx,

медленнее у тебя



Stax,

на первый взгляд достаточно быстро, но точных замеров не стал проводить пока, тк заметил, что и у тебя и у andreymx результаты не сортированные, т.е. результаты для 123 и 132 будет разными. Мне это кажется минусом решения
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851567
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

задача отсортировать не стояла,
имхо сортировка возможно даже искажает результат

мне просто было интересно сравнение древней instr (replace в случае andreymx ) с "навороченной " table of varchar2(100) index by varchar2(1);

.....
stax
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851600
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если уж начался спорт, то что же вы остановились на *символах* строки, и не обобщили до *последовательностей* ?
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851609
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--не обобщили до *последовательностей* ?
Чойта не обобщили-то? 21952734
...
Рейтинг: 0 / 0
подсчет количества уникальных значений в строке
    #39851641
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderandreymx,
медленнее у тебя


от данных зависит

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
вариант Stax - 0.75 сек
SELECT MIN(ff(str)) res
FROM (SELECT 'qwertyuiop[]1234567890asdfghjkl11111111111111111111111111111111111111111111111111122222222222222222222222222222222' str FROM dual connect BY ROWNUM < 30000) t_str;


вариант мой - 0.45 сек
SELECT MIN(ff1(str)) res
FROM (SELECT 'qwertyuiop[]1234567890asdfghjkl11111111111111111111111111111111111111111111111111122222222222222222222222222222222' str FROM dual connect BY ROWNUM < 30000) t_str
...
Рейтинг: 0 / 0
36 сообщений из 36, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подсчет количества уникальных значений в строке
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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