MiksIr, видел я решение на JOIN-ах, фактически это перенос рекурсивных запросов в один длинный, рекурсивно обрабатываемый самой СУБД. Решение кривое и не красивое, к тому-же надо знать уровень вложенности. Я даже видел смешные поделки (в форме готового API обработки деревьев), когда у каждого потомка хранится указатель его уровня вложенности, который используется для генерации SQL запросов с оптимальным уровнем JOIN-ов. Народ изобретает такие велосипеды, что просто удивляешься, (хотя кто их не изобретал).
Мне тоже не понравилось, не красивое, но кривым бы я его не назвал. Нормальное использование возможностей базы.
А кто-нибудь пользуется NESTED SETS? Вопрос хочу задать. Как насисать скрипт, который считает значение верхнего уровня, которое складывается из суммы произведений весов (долей) подчиненых элементов на их значения. Их значения являются так же не абсолютными величинами, а расчитываются по томуже принципу. Абсолютные значения имеют только конечные элементы. Вот написал скриптик. Но он почему-то не идет по уровням в низ, а остановливается на следующем. В чем может быть проблема? Код (Text): <? $result=mysql_query ("SELECT * FROM t_new"); while ($row = mysql_fetch_array($result)) { $lk=$row['left_key']; //Определяем родительский левый ключ $rk=$row['right_key']; // Правый ключ $l=$row['level']; //Родительский уровень $name=$row['name']; $sql1="SELECT value as sumvalue FROM t_new"; $sql2="SELECT SUM(ves*value/100) as sumvalue FROM t_new WHERE left_key >= $lk+1 AND right_key <= $rk-1 AND level=$l+1"; //Если элемент конечный, то его значением будет являться //значение в ячейке БД, если нет, то сумма произведений весов и значений подчиненых элементов $last_el=$rk-$lk; if ($last_el == "1") { $v="$sql1"; $a=mysql_query ("$v"); } else { $v="$sql2"; $a=mysql_query ("$v"); } $result2=$a; while ($row = mysql_fetch_array($result2)) { $sumvalue=$row['sumvalue']; //Считаем первый уровень $result3=mysql_query ("SELECT SUM(ves*$sumvalue/100) as sumvalue FROM t_new WHERE level='2'"); while ($row = mysql_fetch_array($result3)) { $sumvalue=$row['sumvalue']; echo "Сумма $sumvalue<br>"; } } } ?>
user999 Для начала, если ты хочешь в одном цикле все рассчитать, нужно подправить самую первую выборку. Родительское значение нельзя посчитать, пока не станут известны значения всех его потомков, следовательно, выборка должна идти "снизу вверх" - по уменьшению значения left_key.
Вот за утро поправил скриптик, но все равно не работает. Не хочет идти по уровням вниз. Останавливается на следующем. В чем может быть дело? Код (Text): <? //Определяем конечные элементы $result=mysql_query ("SELECT * FROM t_new WHERE right_key-left_key='1'"); while ($row = mysql_fetch_array($result)) { $lk=$row['left_key']; $rk=$row['right_key']; $l=$row['level']; $name=$row['name']; //Определяем родительские элементы конечных элементов $result1=mysql_query ("SELECT * FROM t_new WHERE left_key < $lk AND right_key > $rk AND level=$l-1"); while ($row = mysql_fetch_array($result1)) { $lk=$row['left_key']; $rk=$row['right_key']; $l=$row['level']; $name=$row['name']; //Определяем вес этих родительских элементов $result2=mysql_query ("SELECT SUM(ves*value/100) as sumvalue FROM t_new WHERE left_key > $lk AND right_key < $rk AND level = $l+1"); while ($row = mysql_fetch_array($result2)) { $sumvalue=$row['sumvalue']; $name=$row['name']; //Определяем вес верхнего уровня $result3=mysql_query("SELECT SUM(ves*$sumvalue/100) as sumvalue2 FROM t_new WHERE level='1'"); while ($row = mysql_fetch_array($result3)) { $sumvalue2=$row['sumvalue2']; } } } } ?>
если использовать такое решение то почему бы прямо в цикле не тянуть значения по выбранному айди эл-та? решение с использованием запроса выложено выше, но сейчас пробую реализовать используя массив
Phil, я не понял что Вы имели в виду под фразой Определяем вес этих??? родительских элементов Это Вы у меня спрашиваете или предлагаете определять вес этих элементов. Определить вес родительских эл-тов у меня не получилось, т.к. род. эл может иметь как в своем подчинении конечный элемент , так и неконечный. Вся проблема в том, что я не смог заставить скрипт делать следующее: если элемент не конечный (определяем это с помощью разницы правого и левого ключа) то у него значение будет - сумма произведений веса*значение подчиненных элементов, а если конечный, то указанное хначение. Скрипт не идет по ветке вниз, а останавливается на последующем уровне и принимает значения указанные в ячейках значений (независимо есть они там или их нет). Пробовал писать скрипт с условием: если у элемента значение "0", то его не принимать, а считать по алгоритму, указанному выше. Результат тот же. А по поводу статьи, то я ее читал не однократно, но все равно спасибо за ссылку.[/b]