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


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