powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подсчет количества уникальных значений в строке
25 сообщений из 36, страница 1 из 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
25 сообщений из 36, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подсчет количества уникальных значений в строке
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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