powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пятничная задача: single from
10 сообщений из 35, страница 2 из 2
Пятничная задача: single from
    #40132729
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov,

В твоей итеративной модели можно избавиться от nvl оперируя с iteration_number + 1 вместо iteration_number.

А запись xpath
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132730
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov
pivot c ограничением на целые или pivot xml? или про что речь?
Про unpivot.

Код: plsql
1.
2.
3.
4.
5.
6.
exec dbms_random.seed(1);

create table points(id, x, y) as
select level, dbms_random.value * 10, dbms_random.value * 10
from dual
connect by level <= 2222;



Код: 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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
with t as
(
select t.*,
       (select count(*)
        from points
        where x between t.x - 2 and t.x + 2 and y between t.y - 2 and t.y + 2) cnt
from points t
)
select sum(cnt) from t;

  SUM(CNT)
----------
    636356

Elapsed: 00:00:00.94

with t as
(
select *
from points
model
  dimension by(x, y)
  measures(0 as cnt)
  rules
  (cnt [any, any] order by x, y = count(*)[x between cv(x) - 2 and cv(x) + 2, y between cv(y) - 2 and cv(y) + 2])
)
select sum(cnt) from t;

  SUM(CNT)
----------
    636356

Elapsed: 00:00:01.75

with t as
(
select --+ NO_XML_QUERY_REWRITE
       id,
       x,
       y,
       xmlcast(
         xmlquery(
           'count($D/ROW/VAL[./X >= $X - 2 and ./X <= $X +2 and ./Y >= $Y -2 and ./Y <= $Y +2])'
           passing xmlelement("ROW", (xmlagg(xmlelement(val, xmlelement(x, x), xmlelement(y, y))) over())) as d, x as x, y as y
           returning content) as number) as cnt
from points
)
select sum(cnt) from t;

  SUM(CNT)
----------
    636356

Elapsed: 00:00:43.56

with t as
(
select max(connect_by_root id) id, max(connect_by_root x) x, max(connect_by_root y) y, count(*) cnt
from points t
connect by level <= 2 and id <> prior id and x between prior x - 2 and prior x + 2 and y between prior y - 2 and prior y + 2
group by connect_by_root id, connect_by_root x, connect_by_root y
)
select sum(cnt) from t;

  SUM(CNT)
----------
    636356

Elapsed: 00:02:39.95

with t as
(
select ...
from points t
unpivot ...

)
select sum(cnt) from t;

  SUM(CNT)
----------
    636356

Elapsed: 00:00:05.82


Сравнение просто для информативности.
Понятное дело эта тема ради креатива.

PS. Кстати от connect by я ожидал большего. :)
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132731
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
dbms_photoshop
Про unpivot.
так речь про целые? у меня с самого-самого начала была идея типа
Код: plsql
1.
2.
3.
4.
from points p
unpivot (
  b for a in (x as -2,x as -1, x as 0, x as 1, x as 2)
);

но ты ее зарубил
dbms_photoshop
то есть не обязательно целочисленные как в примере
как ее приспособить для не целых, я что-то даже не стал думать, посчитав, что нельзя...
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132732
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
dbms_photoshop
В твоей итеративной модели можно избавиться от nvl оперируя с iteration_number + 1 вместо iteration_number.
да, я чуял, что где-то напортачил, но было тяжело в такое позднее время да еще после работы уже искать, что я там такого наделал, что у меня 18 итераций на 17 строк получилось
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132733
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
эхъ, баг на баге...
Код: 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 points(ID,X,Y,CNT,DIST) as (
select  1, 1, 1,  5, 61.5629421 from dual union all
select  2, 2, 2, 10, 42.9905342 from dual union all
select  3, 3, 1, 10, 42.3402527 from dual union all
select  4, 3, 2, 13, 33.9007161 from dual union all
select  5, 3, 3, 15, 32.0060445 from dual union all
select  6, 3, 4, 12, 36.5312328 from dual union all
select  7, 4, 1, 10, 40.4182704 from dual union all
select  8, 4, 2, 14, 31.1038271 from dual union all
select  9, 4, 3, 16, 28.2066774 from dual union all
select 10, 4, 4, 14, 32.1841901 from dual union all
select 11, 4, 5, 10, 42.4182704 from dual union all
select 12, 5, 2, 13,  35.300723 from dual union all
select 13, 5, 3, 15, 31.6497533 from dual union all
select 14, 5, 4, 13,  34.916584 from dual union all
select 15, 5, 5, 10, 44.6276236 from dual union all
select 16, 6, 3, 11, 41.6318623 from dual union all
select 17, 6, 4, 10, 44.2841669 from dual 
)
select
    id,x,y,cnt,
                 cardinality( 
                    cast( collect(SYS.KU$_OBJNUM(id))over(order by x range between 2 preceding and 2 following) as sys.ku$_objnumset) 
                    multiset intersect
                    cast( collect(SYS.KU$_OBJNUM(id))over(order by y range between 2 preceding and 2 following) as sys.ku$_objnumset) 
                 )
     as tst
from points
order by id;

ORA-03113: end-of-file on communication channel

...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132734
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Sayan Malakshinov
посчитав, что нельзя...
ааа... дошло... надо было просто
Код: plsql
1.
2.
3.
4.
from points p
unpivot (
  b for a in (x as -2, x as 2)
);
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132735
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov
Код: plsql
1.
collect(...)over(...)

И collect и xmlagg по документации исключительно агрегатные и не аналитические так что тут претензий к Ораклу быть не может.
Sayan Malakshinov
так речь про целые?
Совершенно нет. Я же приложил скрипт создания тестовой таблицы.
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40132737
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
dbms_photoshop
Sayan Malakshinov
Код: plsql
1.
collect(...)over(...)

И collect и xmlagg по документации исключительно агрегатные и не аналитические так что тут претензий к Ораклу быть не может.
Sayan Malakshinov
так речь про целые?
Совершенно нет. Я же приложил скрипт создания тестовой таблицы.
да, блин, хватит ночью писать я и так с бессонницей, теперь ещё тяжелее заснуть когда аж две идеи в голове :(
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40133598
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем основаной намёк был тут 22430093 .
Если там перейти по ссылке то можно было увидеть прикреплённую картинку.

Основная идея состоит в том, чтобы к основному набору добавить его же и искать во вновь добавленном наборе соответствующие строки.
Дублирование исходных данных необходимо потому что pattern matching умеет смотреть только от старта вперёд. *
В отличие от аналитики, где окно может охватывать строки как перед текущей так и после.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
select id_ id, x_ x, y_ y, cnt
from points t
unpivot (id for type in (id as 'original', id as 'new')) upvt
match_recognize
(
  order by type desc, x, y
  measures
    --match_number() mn,
    --classifier() cls,
    first(id) id_,
    first(x) x_,
    first(y) y_,
    count(p.type) cnt
   after match skip to next row
   pattern (strt (p|pp)+)
   define
     strt as strt.type = 'original',
     p as p.type = 'new' and
          p.x >= first(x) - 2 and p.x <= first(x) + 2 and
          p.y >= first(y) - 2 and p.y <= first(y) + 2
) mr
order by 1;



Во второй задаче (подсчет расстояний) мне понадобилась ёще группировка потому что в агрегат нельзя передать значение из первой строки совпавшего набора (match).
Поэтому "all rows per match" с последующим "group by".

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
select id_ id, x_ x, y_ y, sum(dist) dist
from points t
unpivot (id for type in (id as 'original', id as 'new')) upvt
match_recognize
(
  order by type desc, x, y
  measures
    --match_number() mn,
    --classifier() cls,
    first(id) id_,
    first(x) x_,
    first(y) y_,
    sqrt(power(p.x - first(x), 2) + power(p.y - first(y), 2)) dist
   all rows per match
   after match skip to next row
   pattern (strt (p|pp)+)
   define
     strt as strt.type = 'original',
     p as p.type = 'new'
) mr
group by id_, x_, y_
order by 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.
select id_ id, x_ x, y_ y, max(cnt) cnt, sum(dist) dist
from points t
unpivot (id for type in (id as 'original', id as 'new')) upvt
match_recognize
(
  order by type desc, x, y
  measures
    --match_number() mn,
    --classifier() cls,
    first(id) id_,
    first(x) x_,
    first(y) y_,
    count(p2.type) cnt,
    sqrt(power(p.x - first(x), 2) + power(p.y - first(y), 2)) dist
   all rows per match
   after match skip to next row
   pattern (strt (p2|p_|pp)+)
   subset p = (p2, p_)
   define
     strt as strt.type = 'original',
     p2 as p2.type = 'new' and
          p2.x >= first(x) - 2 and p2.x <= first(x) + 2 and
          p2.y >= first(y) - 2 and p2.y <= first(y) + 2,     
     p_ as p_.type = 'new'
) mr
group by id_, x_, y_
order by 1;



* Если б условие было типа такого, то в unpivot необходимости не было бы.
Код: plsql
1.
2.
3.
select t.*,
       (select count(*) from points where x between t.x and t.x + 2 and y between t.y and t.y + 2) cnt
from points t;
...
Рейтинг: 0 / 0
Пятничная задача: single from
    #40134069
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
dbms_photoshop
Код: plsql
1.
2.
3.
from points t
unpivot (id for type in (id as 'original', id as 'new')) upvt
match_recognize

ах, здорово! в голову не пришло, что unpivot с match_recognize вместе могут работать. Да еще я и зашорен был: после игр с match_recognize давным давно, почему-то засело в голову что одна и та же строка не может входить в несколько наборов... Теперь понятно, что это ограничение только стартовой строки.
...
Рейтинг: 0 / 0
10 сообщений из 35, страница 2 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пятничная задача: single from
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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