powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Кохонен на SQL
22 сообщений из 47, страница 2 из 2
Кохонен на SQL
    #37361173
Lucrecia
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В Oracle BI есть готовые функции кластеризации методами K-means и O-means, по Кохонену, вроде бы, нет.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361195
NikNikNikNik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_an_ruтранзитивные запросы и плюс хоть какая-то возможность на каждом шаге сделать временную табличку и при этом залезть в табличку, сделанную на предыдущем шаге. Но вот как вы это потом отлаживать будете?
таки это все есть практически на любой СУБД.
отладка без вопросов - через менеджер или VS
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361199
NikNikNikNik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LucreciaВ Oracle BI есть готовые функции кластеризации методами K-means и O-means, по Кохонену, вроде бы, нет.
пожалуйста, прочтите первый пост - "без использования" интеллектуальных надстроек/расширений СУБД
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361239
Фотография Павел Воронцов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikLucreciaВ Oracle BI есть готовые функции кластеризации методами K-means и O-means, по Кохонену, вроде бы, нет.
пожалуйста, прочтите первый пост - "без использования" интеллектуальных надстроек/расширений СУБДТогда оцените "разработку без использования" в человеко-часах и покажите заказчику, пусть сравнит с опцией "купить надстройки/расширения". Думаю, он выберет второе. Если не дурак.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361303
Lecter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ВоронцовNikNikNikNikпропущено...

пожалуйста, прочтите первый пост - "без использования" интеллектуальных надстроек/расширений СУБДТогда оцените "разработку без использования" в человеко-часах и покажите заказчику, пусть сравнит с опцией "купить надстройки/расширения". Думаю, он выберет второе. Если не дурак.

Если это не какаянить курсовая :)
А по делу, действительно непонятен метод закручивать гвозди когда можно забить( красивый каламбур вышел ) :)
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361392
A
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikLucreciaВ Oracle BI есть готовые функции кластеризации методами K-means и O-means, по Кохонену, вроде бы, нет.
пожалуйста, прочтите первый пост - "без использования" интеллектуальных надстроек/расширений СУБД

Если ситуация такая, что готовых инструментов нет, а сделать надо, например, чтобы вообще проверить подходит ли метод для решения задачи.
Ну и делайте, чем рабочее место позволяет. Я делал в Access (k-means, иерархические и проч.), можно и на PL/SQL. Но вот чистым SQL - а нафига???
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361438
NikNikNikNik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lecter, спасибо за комплимент про возраст - уже проверяю.

a, "а на фига" - для универсальности переноса процедуры/функции с СУБД на СУБД
Если не трудно - чиркните каркас k-means на SQL, спасибо
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361489
A
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikLecter, спасибо за комплимент про возраст - уже проверяю.

a, "а на фига" - для универсальности переноса процедуры/функции с СУБД на СУБД
Если не трудно - чиркните каркас k-means на SQL, спасибо
только на SQL, да еще и универсальном (ANSI?) - не знаю как. И знать не хочу)
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361490
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikдля универсальности переноса процедуры/функции с СУБД на СУБДДля универсальности пишут не sql-запросы, а прослойки между пользователем и данными. Их часто называют "Приложение".
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361497
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikдля универсальности переноса процедуры/функции с СУБД на СУБДБД используется только как хранилище
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361536
Lecter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikLecter, спасибо за комплимент про возраст - уже проверяю.

a, "а на фига" - для универсальности переноса процедуры/функции с СУБД на СУБД
Если не трудно - чиркните каркас k-means на SQL, спасибо

Нет единого стандарта для всех СУБД. Есть АНСИ который полностью не поддерживает ни одна СУБД.
А вот написав приложение на Ява...
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37361542
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNik"а на фига" - для универсальности переноса процедуры/функции с СУБД на СУБДЭто в высшей степени идиотизм.
Рекомендую ознакомится с расшифровкой SQL и подумать хорошо ли он подходит для реализации нейронных алогоритмов.
Ты же если остро нуждаешься в универсальности - напиши на C++ и читай про:
Oracle Calling External Procedures
MSSQL How to: Create and Run a CLR SQL Server User-Defined Function
Как там в других СУБД я не в курсе...

З.Ы. Наглость поражает. Пример данных и результата привести не потрудился зато алгоритм ему набросай.
Все побежали тебе писать Kohonen clustering algorithm based on Oracle model clause.
... Хотя тебе ж это не подойдет, потому как model clause в других СУБД нет. Так что придется выкручиваться рекурсивными запросами, но не думаю что они спасут.
З.З.Ы. Ах да, скажу по секрету, что в каждой СУБД свой диалект SQL.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37364983
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NikNikNikNikЕсли не трудно - чиркните каркас k-means на SQL, спасибоЯ тут решил заняться твоим вопросом исключительно из академического интереса. И все-таки пришел к выводу, что рекурсивным with задача не разрешима.
Рассмотрим пример Numerical Example of K-Means Clustering .
Реализация алгоритма укладывается в довольно компактную функцию
Код: plaintext
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.
create or replace type to_k_means as object (id number, x number, y number, cid number, cx number, cy number)
/
create or replace type tt_k_means as table of to_k_means
/
create or replace function f_k_means(p in tt_k_means) return tt_k_means is
  result     tt_k_means;
  tmp        tt_k_means;
  l_clusters number :=  2 ;
  l_cnt      number;
begin

  select to_k_means(id,
                    x,
                    y,
                    cid,
                    avg(x) over(partition by cid),
                    avg(y) over(partition by cid)) bulk collect
    into result
    from (select M.id,
                 M.x,
                 M.y,
                 c.cid,
                 row_number() over(partition by m.id order by sqrt((m.x - c.x) * (m.x - c.x) + (m.y - c.y) * (m.y - c.y))) rn
            from table(p) M,
                 (select id cid, x, y from table(p) where id <= l_clusters) c)
   where rn =  1 ;

  while true loop
    select to_k_means(id,
                      x,
                      y,
                      cid,
                      avg(x) over(partition by cid),
                      avg(y) over(partition by cid)) bulk collect
      into tmp
      from (select id,
                   x,
                   y,
                   t.cid,
                   row_number() over(partition by id order by sqrt((x - t.cx) * (x - t.cx) + (y - t.cy) * (y - t.cy))) rn
              from table(result),
                   (select distinct cid, cx, cy from table(result)) t)
     where rn =  1 ;
  
    select count(*)
      into l_cnt
      from table(tmp) t1, table(result) t2
     where t1.id = t2.id
       and t1.cid = t2.cid;
  
    if l_cnt = result.count then
      exit;
    else
      result := tmp;
    end if;
  end loop;

  return result;

end f_k_means;
/
И для тестровых данных получаем вполне ожидаемый результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> select *
   2     from table(f_k_means(tt_k_means(to_k_means( 1 ,  1 ,  1 , null, null, null),
   3                                     to_k_means( 2 ,  2 ,  1 , null, null, null),
   4                                     to_k_means( 3 ,  4 ,  3 , null, null, null),
   5                                     to_k_means( 4 ,  5 ,  4 , null, null, null))));
 
        ID          X          Y        CID         CX         CY
---------- ---------- ---------- ---------- ---------- ----------
          1            1            1            1          1 , 5            1 
          2            2            1            1          1 , 5            1 
          3            4            3            2          4 , 5          3 , 5 
          4            5            4            2          4 , 5          3 , 5 
CID - номер кластера, (CX;CY) - центр соответствующего кластера.

Если посмотреть код функции, то может возникнуть мысль, что можно копнуть в сторону рекурсивного with, но при дальнейшем рассмотрении сразу сталкиваешься со следующими ограничениями:
1. В рекурсивной части запроса нельзя ссылаться на самого себя в inline view.
Код: plaintext
ORA- 32042 : recursive WITH clause must reference itself directly in one of the UNION ALL branches
2. В рекурсивной части не могут быть использованы аналитические функции:
Код: plaintext
1.
2.
3.
4.
ORA- 32486 : unsupported operation in recursive branch of recursive WITH clause
    Cause: The recursive component of the UNION ALL in a recursive WITH clause element used an operation that was currently not
supported. The following should not be used in the recursive branch of the UNION ALL operation: GROUP BY, DISTINCT, MODEL,
grouping sets, CONNECT BY, window functions, HAVING, aggregate functions.
    Action: Rewrite the query without the unsupported operation.
В МССКЛ подобных ограничений нет. Но во-первых там аналитика в рекурсивной части хоть и раобтает, но толку от нее нет . А во-вторых как бы там ни было ссылаться в рекурсивной компоненте на самого себя можно только однократно . С таким ограничением реализовать алгоритм, я думаю, невозможно.

Безусловно на model clause все решаемо, но тоже не особо изящно и эффективно. :)
...
Рейтинг: 0 / 0
Кохонен на SQL
    #37370202
NikNikNikNik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop, спасибо, круто
бум потетсировать
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кохонен на SQL
    #39159324
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С 2011 прошли заметные улучшения, может кому-нибудь будет полезно.

1. Кластеризовать можно вообще не создавая никаких моделей 12с
Код: 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.
SQL> create or replace type to_cluster force as object (cluster_id number, probability binary_double)
  2  /

Type created.

SQL> create or replace type tt_cluster as varray (2147483647) of to_cluster
  2  /

Type created.

SQL> set lines 150 pages 150
SQL> set long 1000
SQL> column id format 99
SQL> column x format 99
SQL> column y format 99
SQL> column c format 99
SQL> column probability format 0.999999999
SQL> column distance format 999.999999
SQL> column cluster_details format a65
SQL> column cluster_set format a70
SQL> with t as
  2  (
  3  select 1 id, 1 x, 2 y from dual
  4  union all select 2 id, 2 x, 1 y from dual
  5  union all select 3 id, 4 x, 3 y from dual
  6  union all select 4 id, 5 x, 4 y from dual
  7  )
  8  select id,
  9         x,
 10         y,
 11         cluster_id(into 2 using x, y) over() c,
 12         cluster_probability(into 2 using x, y) over() probability,
 13         cluster_distance(into 2 using x, y) over() distance,
 14         cast(cluster_set(into 2 using x, y) over() as tt_cluster) cluster_set,
 15         cluster_details(into 2 using x, y) over() cluster_details
 16    from t;

 ID   X   Y   C  PROBABILITY    DISTANCE CLUSTER_SET(CLUSTER_ID, PROBABILITY)
--- --- --- --- ------------ ----------- ----------------------------------------------------------------------
CLUSTER_DETAILS
-----------------------------------------------------------------
  1   1   2   3  0.999841564    9.140625 TT_CLUSTER(TO_CLUSTER(3, 9.998E-001), TO_CLUSTER(2, 1.584E-004))
<Details algorithm="K-Means Clustering" cluster="3">
<Attribute name="X" actualValue="1" weight=".119" rank="1"/>
<Attribute name="Y" actualValue="2" weight=".001" rank="2"/>
</Details>

  2   2   1   3  0.999915189    9.765625 TT_CLUSTER(TO_CLUSTER(3, 9.999E-001), TO_CLUSTER(2, 8.481E-005))
<Details algorithm="K-Means Clustering" cluster="3">
<Attribute name="Y" actualValue="1" weight=".033" rank="1"/>
<Attribute name="X" actualValue="2" weight=".002" rank="2"/>
</Details>

  3   4   3   2  0.995390428    5.765625 TT_CLUSTER(TO_CLUSTER(2, 9.954E-001), TO_CLUSTER(3, 4.61E-003))
<Details algorithm="K-Means Clustering" cluster="2">
<Attribute name="X" actualValue="4" weight=".115" rank="1"/>
<Attribute name="Y" actualValue="3" weight=".028" rank="2"/>
</Details>

  4   5   4   2  0.999997098   13.140625 TT_CLUSTER(TO_CLUSTER(2, 1.0E+000), TO_CLUSTER(3, 2.902E-006))
<Details algorithm="K-Means Clustering" cluster="2">
<Attribute name="X" actualValue="5" weight=".002" rank="1"/>
<Attribute name="Y" actualValue="4" weight=".001" rank="2"/>
</Details>


2. Можно использовать функции cluster_* c указанием модели, но имеется только 3 алгоритма кластеризации:
k-Means, O-Cluster, or Expectation Maximization .
Есть возможность конфигурировать небольшое число настроек для каждого.

3. Если хочется полной гибкости - есть возможность прикрутить абсолютно любой алгоритм на R language с помощью ORE ( 11.2.0.3/4 или 12с ).
Oracle R Enterprise Embedded SQL Scripts .
В том числе Self-Organising Maps by Kohonen .
Кроме того получить визуализацию результата из R и отобразить с помощью, например, OBIEE.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #39159372
Фотография iv_an_ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

Спасибо.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #39159560
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopесть возможность прикрутить абсолютно любой алгоритм на R language с помощью OREТут стоит уточнить, что хотя R и называют языком программирования, но он является всего лишь крайне скудным (имхо) интерпретируемым языком.
Все "умные алгоритмны" написаны как правило на С и могут быть использованы в R через библиотеки.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #39163973
Uchastneg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop3. Если хочется полной гибкости - есть возможность прикрутить абсолютно любой алгоритм на R language

смотря еще, какой объем данных..
возможно, проще будет воспользоваться Python, выгрузить в панду (pandas),
а дальше уже гибкость максимальная - и кластеризация, и классификация, и визуализация, и универсальность БД )
...
Рейтинг: 0 / 0
Кохонен на SQL
    #39167804
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Uchastnegсмотря еще, какой объем данных..
возможно, проще будет воспользоваться Python, выгрузить в панду (pandas),
а дальше уже гибкость максимальная - и кластеризация, и классификация, и визуализация, и универсальность БД )Насколько я понимаю pandas - дополнительный пакет/библиотека к python, который содержит только базовые вещи для анализа и выгрузки/загрузки данных.
Она не содержит, например, "Self-Organising Maps by Kohonen" о чем шла речь в этом топике.
И хоть этот пакет (kohonen) можно скачать в дополнение к python, но все равно не совсем понятно какой это дает профит по сравнению с использованием R.

С одной стороны при наличии Advance Analytics option, использование R достигается через вызов extproc from Oracle, можно сохранять определения R функций прямо в базе для дальнейшего вызова и прочее.

Но с другой стороны, опция стоит 23к и если цель только использовать внешние библиотеки анализа данных, то вряд ли имеет смысл платить. В конце концов написать свою библиотеку, вызывающую любую необходимую библиотеку python это дело пары дней, так что выбор R vs python для меня не очень очевиден.
Хотя если в python нет дефолтных ограничений по памяти и параллельности как в R (которые обходятся танцами с бубном), то это ему большой плюс.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кохонен на SQL
    #40124561
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нижесказанное имеет некоторое отношение к сравнению СУБД, надеюсь модераторы меня простят.
Акцент таки на возможностях Оракла.

Это был достаточно интересный пример для анализа возможностей rec CTE.
Что по сути требуется - это выполнять в рекурсивном члене аналитику и группировку.
Группировка невозможна ни в одной из имеющихся у меня под рукой СУБД (Oracle, MSSQL, PG),
но агрегатные функции можно корявенько заменить на аналитика + distinct или аналитика + фильтр по row_number.

dbms_photoshop
Если посмотреть код функции, то может возникнуть мысль, что можно копнуть в сторону рекурсивного with, но при дальнейшем рассмотрении сразу сталкиваешься со следующими ограничениями:
1. В рекурсивной части запроса нельзя ссылаться на самого себя в inline view.
Код: plsql
1.
ORA-32042: recursive WITH clause must reference itself directly in one of the UNION ALL branches

Вот это допустимо в PG или MSSQL в отличие от Оракл.

dbms_photoshop
2. В рекурсивной части не могут быть использованы аналитические функции:
Код: plsql
1.
2.
3.
4.
5.
ORA-32486: unsupported operation in recursive branch of recursive WITH clause
    Cause: The recursive component of the UNION ALL in a recursive WITH clause element used an operation that was currently not
supported. The following should not be used in the recursive branch of the UNION ALL operation: GROUP BY, DISTINCT, MODEL,
grouping sets, CONNECT BY, window functions, HAVING, aggregate functions.
    Action: Rewrite the query without the unsupported operation.

Это неверное описание cause и аналитические функции были допустимы в рекурсивном члене даже в 11.2.
Вообще, насколько мне известно, в плане возможностей rec with ничего не поменялось с 11.2 до 21с. (однако в плане производительности и оптимизации много изменений)

Итак, в плане ограничений в рекурсивном члене можно привести такую таблицу
ORA PG MSSQLdistinct - + -group by - - -subquery - + +analytics + + +(*)
Или чуть подробнее
- distinct реализован только в PG
- агрегатные функции недопустимы нигде
- использование имени CTE в подзапросе невозможно только в Оракл, что сильно ограничивает потенциал
- использование аналитики возможно везде но в МССКЛ работает кривовато.
про кривоватоВ МССКЛ аналитика работает над набором строк полученным от конкретного родителя а не над всем набором строк на данном шаге.
Это согласно документации, но всё равно имеет мало смысла на мой взгляд.
В примере ниже сумма на третьем уровне посчитана для каждого из родителей отдельно в случае МССКЛ.
Код: sql
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.
with
tree(id, parent, value) as
(
select 1, null, 100
union all select 2, 1, 1
union all select 0, 1, 1
union all select 3, 2, 11
union all select 4, 2, 1
union all select 5, 2, 111
union all select 22, 0, 222
)
, r(lvl, id, parent, sm) as
(
select 1, id, parent, sum(value) over ()
  from tree
 where parent is null
union all
select lvl+1, t.id, t.parent, sum(value) over ()
  from r
  join tree t on t.parent = r.id
)
select *
from r;

lvl         id          parent      sm
----------- ----------- ----------- -----------
1           1           NULL        100
2           2           1           2
2           0           1           2
3           22          0           222
3           3           2           123
3           4           2           123
3           5           2           123

(7 rows affected)


PG
Код: sql
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.
postgres=# with recursive
postgres-# tree(id, parent, value) as
postgres-# (
postgres(# select 1, null, 100
postgres(# union all select 2, 1, 1
postgres(# union all select 0, 1, 1
postgres(# union all select 3, 2, 11
postgres(# union all select 4, 2, 1
postgres(# union all select 5, 2, 111
postgres(# union all select 22, 0, 222
postgres(# )
postgres-# , r(lvl, id, parent, sm) as
postgres-# (
postgres(# select 1, id, parent, sum(value) over ()
postgres(#   from tree
postgres(#  where parent is null
postgres(# union all
postgres(# select lvl+1, t.id, t.parent, sum(value) over ()
postgres(#   from r
postgres(#   join tree t on t.parent = r.id
postgres(# )
postgres-# select *
postgres-# from r;
 lvl | id | parent | sm
-----+----+--------+-----
   1 |  1 |        | 100
   2 |  0 |      1 |   2
   2 |  2 |      1 |   2
   3 | 22 |      0 | 345
   3 |  5 |      2 | 345
   3 |  4 |      2 | 345
   3 |  3 |      2 | 345
(7 rows)


Oracle
Код: 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.
SQL> with
  2  tree(id, parent, value) as
  3  (
  4  select 1, null, 100 from dual
  5  union all select 2, 1, 1 from dual
  6  union all select 0, 1, 1 from dual
  7  union all select 3, 2, 11 from dual
  8  union all select 4, 2, 1 from dual
  9  union all select 5, 2, 111 from dual
 10  union all select 22, 0, 222 from dual
 11  )
 12  , r(lvl, id, parent, sm) as
 13  (
 14  select 1, id, parent, sum(value) over ()
 15    from tree
 16   where parent is null
 17  union all
 18  select lvl+1, t.id, t.parent, sum(value) over ()
 19    from r
 20    join tree t on t.parent = r.id
 21  )
 22  select *
 23  from r;

       LVL         ID     PARENT         SM
---------- ---------- ---------- ----------
         1          1                   100
         2          2          1          2
         2          0          1          2
         3          3          2        345
         3          4          2        345
         3          5          2        345
         3         22          0        345

7 rows selected.




Итого, в МССКЛ задача нерешаема из-за кривости с аналитикой, в Оракл задача нерешаема т.к. нельзя ссылаться на имя CTE в подзапросе. А вот в PG решение может быть, например, таким.
Код: sql
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.
postgres=# with recursive
postgres-# p(id, x, y) as
postgres-# (
postgres(# select 1, 1, 1 --from dual
postgres(# union all select 2, 2, 1 --from dual
postgres(# union all select 3, 4, 3 --from dual
postgres(# union all select 4, 5, 4 --from dual
postgres(# ),
postgres-# r(lvl, cid, cx, cy, members) as
postgres-#  (select distinct lvl,
postgres(#                   cid,
postgres(#                   avg(x) over(partition by cid),
postgres(#                   avg(y) over(partition by cid),
postgres(#                   string_agg('('||cid||' '||id||')', ', ') over ()
postgres(#     from (select m.id,
postgres(#                  m.x,
postgres(#                  m.y,
postgres(#                  1 lvl,
postgres(#                  c.cid,
postgres(#                  row_number() over(partition by m.id order by sqrt((m.x - c.cx) * (m.x - c.cx) + (m.y - c.cy) * (m.y - c.cy))) rn
postgres(#             from p m, (select id cid, x cx, y cy from p where id <= 2) c) sq
postgres(#    where rn = 1
postgres(#   union all
postgres(#   select lvl, cid, cx, cy, members
postgres(#     from (select distinct lvl,
postgres(#                           cid,
postgres(#                           avg(x) over(partition by cid) cx,
postgres(#                           avg(y) over(partition by cid) cy,
postgres(#                           string_agg('('||cid||' '||id||')', ', ') over () members,
postgres(#                           prev_members
postgres(#             from (select m.id,
postgres(#                          m.x,
postgres(#                          m.y,
postgres(#                          c.lvl + 1 lvl,
postgres(#                          c.cid,
postgres(#                          row_number() over(partition by m.id order by sqrt((m.x - c.cx) * (m.x - c.cx) + (m.y - c.cy) * (m.y - c.cy))) rn,
postgres(#                          c.members prev_members
postgres(#                     from p m, r c) sq
postgres(#            where rn = 1) sq
postgres(#    where members <> prev_members)
postgres-# select * from r;
 lvl | cid |           cx           |           cy           |          members
-----+-----+------------------------+------------------------+----------------------------
   1 |   1 | 1.00000000000000000000 | 1.00000000000000000000 | (1 1), (2 2), (2 3), (2 4)
   1 |   2 |     3.6666666666666667 |     2.6666666666666667 | (1 1), (2 2), (2 3), (2 4)
   2 |   1 |     1.5000000000000000 | 1.00000000000000000000 | (1 1), (1 2), (2 3), (2 4)
   2 |   2 |     4.5000000000000000 |     3.5000000000000000 | (1 1), (1 2), (2 3), (2 4)
(4 rows)



dbms_photoshop
Безусловно на model clause все решаемо, но тоже не особо изящно и эффективно. :)
Для полноты картины приведу и сие.
Код: 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.
SQL> with p(id, x, y) as
  2  (
  3  select 1, 1, 1 from dual
  4  union all select 2, 2, 1 from dual
  5  union all select 3, 4, 3 from dual
  6  union all select 4, 5, 4 from dual
  7  ),
  8  m as
  9  (
 10  select *
 11  from
 12  (select m.*, cid, cx, cy from p m, (select id cid, x cx, y cy from p where id <= 2) c) t
 13  model
 14  dimension by (id, cid)
 15  measures (x, y, 0 rn, cx, cy, cast(null as varchar2(4000)) members, 0 i)
 16  rules sequential order iterate(1e9) until (members[1, 1] = previous(members[1, 1]))
 17  (
 18    rn[any, any] = row_number() over(partition by id order by sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))),
 19    cx[any, any] = avg(decode(rn, 1, x))[any, cv(cid)],
 20    cy[any, any] = avg(decode(rn, 1, y))[any, cv(cid)],
 21    -- "sign(iteration_number)" to force re-evaluation on each iteration
 22    -- (otherwise members are calculated on 1st iteration only and it looks like a bug)
 23    members[any, any] = listagg(decode(rn * sign(iteration_number), 1, '('||cid||' '||id||')'), ', ') within group (order by cid, id) over (),
 24    i[any, any] = iteration_number + 1
 25  )
 26  )
 27  select *
 28  from m
 29  where rn = 1
 30  order by 1, 2;

        ID        CID          X          Y         RN         CX         CY MEMBERS                                 I
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------------------------ ----------
         1          1          1          1          1        1.5          1 (1 1), (1 2), (2 3), (2 4)              2
         2          1          2          1          1        1.5          1 (1 1), (1 2), (2 3), (2 4)              2
         3          2          4          3          1        4.5        3.5 (1 1), (1 2), (2 3), (2 4)              2
         4          2          5          4          1        4.5        3.5 (1 1), (1 2), (2 3), (2 4)              2
...
Рейтинг: 0 / 0
Кохонен на SQL
    #40124562
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кратко, два основных тезиса
1. PG явный лидер в плане возможностей для рекурсивных запросов т.к. позволяет реализовывать более сложную логику в рекурсивном члене.
2. Я не вижу фундаментальных причин запрещать агрегатные функции в рекурсивном члене. Может я что-то упускаю, а возможно это появится в будущем.
...
Рейтинг: 0 / 0
Кохонен на SQL
    #40124564
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop
Я не вижу фундаментальных причин запрещать агрегатные функции в рекурсивном члене. Может я что-то упускаю, а возможно это появится в будущем.
Возможно, дело в том, что выполнение группировки очень редко необходимо именно во время выполнения recursive CTE.
Достаточно часто, когда может возникнуть мысль о группировке в recursive member referring CTE name, можно группировку выполнить уже после того как иерархия построена.
Например, когда надо посчитать агрегат для каждого узла путём соединения построенной иерархии с какой-то детализирующей таблицей.

Если же требуется группировка в recursive member query block which does not refer CTE name, то это вполне возможно в Оракл.
Парочку примеров тут Пятничная задача: работнички.
...
Рейтинг: 0 / 0
22 сообщений из 47, страница 2 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Кохонен на SQL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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