[solved][SQL] неопределенное количество JOIN

khachin

Help me, Optimus. I'm stuck...
Попробую сформулировать задачу.
Есть некий завод по производству продукции: Продукт_А, Продукт_Б, Продукт_В...
На заводе делаются сборки: Сборка_А1, Сборка_А2, Сборка_Б1, Сборка_Б2, Сборка_Б3...
Каждая сборка может иметь подсборки, входящие в нее...
Для упорядоченной иерархии в базе заведена таблица из полей:
construction_id(FK,PK member_of_id(FK,PK)
Используется для связи many-to-one (с готовностью перейти в перспективе к many-to-many, поэтому не удивляйтесь такой связи). Слева записывается id подсборки, справа — id сборки в которую подсборка включается.
(Далее конфлюентом бесполезная информация для полноты задачи...)

В чем сложность: известно id детали (значение в construction_id известно id сборки (значение в member_of_id но неизвестно количество связей, в которых участвует таблица, чтобы добраться до интересующего уровня. Т.е. количество связей переменно.
Для таких вещей есть готовые решения?

kill-still

Диалект я что-то не заметил в тексте.
если pl/sql, то тебе сюда: http://docs.oracle.com/cd/B19306_01/server.102/b14200/querie...
если mssql, то сюда: http://technet.microsoft.com/ru-ru/library/ms186243%28v=sql....
если другие, то только сюда: http://en.wikipedia.org/wiki/Nested_set_model

Alena_08_11

 Если останется many to one (сборка - корень иерархии, далее подсборки ..... и на листьях конечные детали. т.е. исключается когда одна и таже подсборка является частью разных сборок).
То можно один раз построить деревья сборок и обходом по часовой стрелке от корня пронумеровать левые и правые границы узлов :

....
Сборка A (1, 14) -> Подсборка А1 (2,7) -> Деталь А11(3,4) , Деталь А12 (5,6)
     Подсборка А2 (8,13) -> Деталь А21(9,10) , Деталь А12 (11,12)
...

Ну и далее join с условием Cборка.ЛеваяГраница <= Деталь.ЛеваяГраница and Сборка.ПраваяГраница >= Деталь.ПраваяГраница и sum по TotalAmount
Вместо сборки, можно любую подсборку и даже саму деталь (поэтому <= и >=)
Короче хз как это называется по научному - но подход тысячу раз описан как одна из реализацией бухгалтерского плана счетов.
ps. Это если я правильно понял задачу.

khachin

Идея интересная.
Как я понял, для этого требуется завести еще два поля (левая и правая границы а при появлении нового элемента в дереве проводить пересчет?

khachin

Погуглил статьи на тему nested sets. Действительно, классическое решение проблемы — задать границы. На хабре есть решение через триггеры, но я их стараюсь по возможности избегать. Всем спасибо за заданный вектор.

Alena_08_11

А блин
Nested sets это называется оказывается :)

hprt

Так какая субд все же? Может, не надо велосипед изобретать

khachin

Я в любом случае работаю через sqlalchemy. Но если интересно, интерфейс связывается с postgresql.
Таблицу для nested sets завел. Работает, как часы.
На днях ивенты пропишу, готовые примеры есть на sqlalchemy.org.

hprt

честно говоря, не представляю, что такое sql alchemy, но постгре вроде как умеет делать рекурсивные запросы. Тогда вопрос, зачем делать очередной велосипед. http://www.postgresql.org/docs/8.4/static/queries-with.html

khachin

Потому в первом посте и стоял вопрос: есть ли готовые решения?
Про рекурсивный запрос в postrge читал, но не вникал. На досуге попробую, спасибо. Можно для справки, какие СУБД еще умеют рекурсивный запрос проводить?

hprt

надо смотреть по каждой отдельно. В оракле эта штука очень давно есть в виде адского connect by, в таком виде не так давно появилось вроде. В мс есть. Вообще, кротишка же тебе ссылки привел :) Есть ли в мускуле - не знаю, про дб2 и сайбейс тоже, про остальные тем более не в курсе

abur

connect by естьи в постгре в специальном пакете,и кстати довольно инетерсная штука.

hprt

возможно, я постгре почти не знаю

Andbar

В оракле эта штука очень давно есть в виде адского connect by
Почему это адского? В целом смысл примерно сравним с тем, что есть в стандарте (я так понимаю, рекурсия в стандарте появилась уже после её реализации в оракле при этом не нужно связываться с подзапросом, описываемым в with. Как плюс - некоторое количество доп. функций, работающих именно с рекурсией

hprt

потому что синтаксис неочевидный. Рекурсию в стандарт привел МС, и да, в оракле она была задолго до этого. Но как обычно, МС смотрит на крутые фичи других и делает удобно. Я сейчас занимаюсь обучением сиквелу с нуля, так вот синтаксис с with абсолютно нетехнические люди понимают, потому что он интуитивно понятный, connect by, думаю вряд ли бы поняли сразу. Что уж там, профи, бывает, сидят долго курят, что же с этими доп опциями написали (было дело в люксофте - в итоге как раз через with переписали, не я)

apl13

МС смотрит на крутые фичи других и делает удобно
Что такое МС в данном контексте?

hprt

смотрит на крутые фичи других и делает удобно
Что такое МС в данном контексте?
микрософт

apl13

микрософт
делает удобно
Sorry, what?!
Оставить комментарий
Имя или ник:
Комментарий: