powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Динамическая классификация выборки
4 сообщений из 4, страница 1 из 1
Динамическая классификация выборки
    #39977452
ora0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, доброго дня
Есть задача проклассифицировать выборку по динамическим правилам.
Навскидку набросал решение, но в части оптимальности (в т.ч. по скорости) нет увернности.
Хочется мнение общественности, как можно улучшить сей код или в принципе поменять подход:

--NLS_RDBMS_VERSION=19.0.0.0.0

Код: 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.
62.
63.
64.
declare
  TYPE TuneRec is record (condition varchar2(200), classcode varchar2(200));
  TYPE TunesTable is table of TuneRec index by binary_integer;
  tunes TunesTable;
  idx binary_integer;
  plsql_block varchar2(500);
  real_condition varchar2(500);
  res number;
begin
    --таблица правил классификации, размер реальной таблицы - пару тысяч записей    
    --в condition до 100 разных параметров [PAR*] в разных комбинациях
    with c
    as
    (
        select rownum id, t.*
        from
        (
        select 1 prioritet, '''[PAR1]'' = ''F'' and ''[PAR2]'' like ''mos%''' condition, 'A' classcode from dual
        union
        select 2 , '''[PAR1]'' = ''F'' and ''[PAR2]'' like ''san%''', 'B' from dual
        union
        select 3 , '''[PAR2]'' like ''%burg%''', 'C' from dual
        union
        select 4 , '1=1', 'Z' from dual
        ) t
     )
    select c.condition, c.classcode
    BULK COLLECT INTO tunes
    from c
    order by c.prioritet;
    
    --запрос по классифицируемым сущностям, в реальном запросе - сотни тысяч записей
    for q in (
      select 'F' p1, 'moscow' p2 from dual
      union
      select 'F', 'sankt petersburg' from dual
      union
      select 'B', 'ekaterinburg' from dual
      union
      select 'B', 'novosibirsk' from dual
    ) loop
      dbms_output.put_line(q.p1||' '||q.p2);
      idx := tunes.first;
      while idx is not null
      loop
        --dbms_output.put_line(tunes(idx).condition);
        real_condition := replace(tunes(idx).condition,'[PAR1]', q.p1);
        real_condition := replace(real_condition,'[PAR2]', q.p2);
        --replace [PAR3], replace [PAR4]...
        --dbms_output.put_line(real_condition);
        
        plsql_block := 'SELECT case when '||real_condition||' then 1 else 0 end from dual';
        --dbms_output.put_line(plsql_block);
        EXECUTE IMMEDIATE plsql_block into res;
        --dbms_output.put_line('res='||to_char(res));
        if res = 1 then
          dbms_output.put_line('classcode='||tunes(idx).classcode);
          exit;
        end if;
        
        idx := tunes.next(idx);
      end loop;
    end loop;
end;



Результат:
B ekaterinburg
'B' = 'F' and 'ekaterinburg' like 'mos%'
'B' = 'F' and 'ekaterinburg' like 'san%'
'ekaterinburg' like '%burg%'
classcode=C
B novosibirsk
'B' = 'F' and 'novosibirsk' like 'mos%'
'B' = 'F' and 'novosibirsk' like 'san%'
'novosibirsk' like '%burg%'
1=1
classcode=Z
F moscow
'F' = 'F' and 'moscow' like 'mos%'
classcode=A
F sankt petersburg
'F' = 'F' and 'sankt petersburg' like 'mos%'
'F' = 'F' and 'sankt petersburg' like 'san%'
classcode=B

Это прототип, на реальных данных не гоняли.
Подход, в том числе к настройкам классификации, можно обсуждать и менять.
...
Рейтинг: 0 / 0
Динамическая классификация выборки
    #39977748
Фотография Egoр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ora0,
что мешает такую конструкцию использовать
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with c
    as
    (
        select rownum id, t.*
        from
        (
        select 1 prioritet, '''[PAR1]'' = ''F'' and ''[PAR2]'' like ''mos%''' condition, 'A' classcode from dual
        union
        select 2 , '''[PAR1]'' = ''F'' and ''[PAR2]'' like ''san%''', 'B' from dual
        union
        select 3 , '''[PAR2]'' like ''%burg%''', 'C' from dual
        union
        select 4 , '1=1', 'Z' from dual
        ) t
     )
    select ListAGG('case when ' || condition || ' then '''|| classcode || ';'' end ', ' ||
') within group (order by prioritet)
 into vClsCase
    from c
...
Рейтинг: 0 / 0
Динамическая классификация выборки
    #39977754
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Egoр,

если я правильно понял ora0 надо проверить/выполнить формулы (EXECUTE IMMEDIATE), а не сформировать в "строку"

ps
plsql_block возможно я б делал как блок (begin end; - без селекта), но зависит от реального использования "макросов"


....
stax
...
Рейтинг: 0 / 0
Динамическая классификация выборки
    #39977757
Фотография Egoр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
если я правильно понял ora0 надо проверить/выполнить формулы (EXECUTE IMMEDIATE), а не сформировать в "строку"
....
stax

Точно! Как же я не заметил, что ТС результаты через output собирается обрабатывать! ;-)
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Динамическая классификация выборки
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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