За последние 24 часа нас посетили 60294 программиста и 1815 роботов. Сейчас ищут 857 программистов ...

Рекурсия

Тема в разделе "PHP для новичков", создана пользователем phil, 4 апр 2007.

  1. ONK

    ONK Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    281
    Симпатии:
    0
    Адрес:
    СПб
    MiksIr, видел я решение на JOIN-ах, фактически это перенос рекурсивных запросов в один длинный, рекурсивно обрабатываемый самой СУБД.
    Решение кривое и не красивое, к тому-же надо знать уровень вложенности. Я даже видел смешные поделки (в форме готового API обработки деревьев), когда у каждого потомка хранится указатель его уровня вложенности, который используется для генерации SQL запросов с оптимальным уровнем JOIN-ов. Народ изобретает такие велосипеды, что просто удивляешься, (хотя кто их не изобретал). ;)
     
  2. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Мне тоже не понравилось, не красивое, но кривым бы я его не назвал. Нормальное использование возможностей базы.
     
  3. user999

    user999 Активный пользователь

    С нами с:
    17 ноя 2006
    Сообщения:
    57
    Симпатии:
    0
    А кто-нибудь пользуется NESTED SETS?
    Вопрос хочу задать.
    Как насисать скрипт, который считает значение верхнего уровня, которое складывается из суммы произведений весов (долей) подчиненых элементов на их значения. Их значения являются так же не абсолютными величинами, а расчитываются по томуже принципу. Абсолютные значения имеют только конечные элементы.
    Вот написал скриптик. Но он почему-то не идет по уровням в низ, а остановливается на следующем. В чем может быть проблема?

    Код (Text):
    1.  
    2. <?
    3.  $result=mysql_query ("SELECT * FROM t_new");
    4.     while ($row = mysql_fetch_array($result)) {
    5.     $lk=$row['left_key'];       //Определяем родительский левый ключ
    6.     $rk=$row['right_key'];      // Правый ключ
    7.     $l=$row['level'];           //Родительский уровень
    8.     $name=$row['name'];
    9.     $sql1="SELECT value as sumvalue FROM t_new";
    10.     $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";
    11.  
    12.     //Если элемент конечный, то его значением будет являться
    13.     //значение в ячейке БД, если нет, то сумма произведений весов и значений подчиненых элементов
    14.     $last_el=$rk-$lk;
    15.     if ($last_el == "1") {
    16.     $v="$sql1";
    17.     $a=mysql_query ("$v");
    18.      } else {
    19.      $v="$sql2";
    20.      $a=mysql_query ("$v");
    21.      }
    22.  
    23.  $result2=$a;
    24.    while ($row = mysql_fetch_array($result2)) {
    25.     $sumvalue=$row['sumvalue'];
    26.    //Считаем первый уровень
    27.     $result3=mysql_query ("SELECT SUM(ves*$sumvalue/100) as sumvalue FROM t_new  WHERE level='2'");
    28.     while ($row = mysql_fetch_array($result3)) {
    29.         $sumvalue=$row['sumvalue'];
    30.         echo "Сумма $sumvalue<br>";
    31.  
    32.         }
    33.  
    34.     }
    35.  
    36.  }
    37.  ?>
     
  4. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    user999
    Для начала, если ты хочешь в одном цикле все рассчитать, нужно подправить самую первую выборку. Родительское значение нельзя посчитать, пока не станут известны значения всех его потомков, следовательно, выборка должна идти "снизу вверх" - по уменьшению значения left_key.
     
  5. user999

    user999 Активный пользователь

    С нами с:
    17 ноя 2006
    Сообщения:
    57
    Симпатии:
    0
    Вот за утро поправил скриптик, но все равно не работает. Не хочет идти по уровням вниз. Останавливается на следующем. В чем может быть дело?

    Код (Text):
    1.  
    2.  <?
    3.  //Определяем конечные элементы
    4.  $result=mysql_query ("SELECT * FROM t_new WHERE right_key-left_key='1'");
    5.     while ($row = mysql_fetch_array($result)) {
    6.     $lk=$row['left_key'];
    7.     $rk=$row['right_key'];
    8.     $l=$row['level'];
    9.     $name=$row['name'];
    10.  
    11.     //Определяем родительские элементы конечных элементов
    12.     $result1=mysql_query ("SELECT * FROM t_new WHERE left_key < $lk AND right_key > $rk AND level=$l-1");
    13.     while ($row = mysql_fetch_array($result1)) {
    14.     $lk=$row['left_key'];
    15.     $rk=$row['right_key'];
    16.     $l=$row['level'];
    17.     $name=$row['name'];
    18.  
    19.     //Определяем вес этих родительских элементов
    20.     $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");
    21.       while ($row = mysql_fetch_array($result2)) {
    22.     $sumvalue=$row['sumvalue'];
    23.     $name=$row['name'];
    24.  
    25.      //Определяем вес верхнего уровня
    26.     $result3=mysql_query("SELECT SUM(ves*$sumvalue/100) as sumvalue2 FROM t_new WHERE level='1'");
    27.      while ($row = mysql_fetch_array($result3)) {
    28.      $sumvalue2=$row['sumvalue2'];
    29.      }
    30.     }
    31.   }
    32.  }
    33.  ?>
     
  6. phil

    phil Активный пользователь

    С нами с:
    4 апр 2007
    Сообщения:
    62
    Симпатии:
    0

    если использовать такое решение то почему бы прямо в цикле не тянуть значения по выбранному айди эл-та?

    решение с использованием запроса выложено выше, но сейчас пробую реализовать используя массив
     
  7. phil

    phil Активный пользователь

    С нами с:
    4 апр 2007
    Сообщения:
    62
    Симпатии:
    0
  8. user999

    user999 Активный пользователь

    С нами с:
    17 ноя 2006
    Сообщения:
    57
    Симпатии:
    0
    Phil, я не понял что Вы имели в виду под фразой Определяем вес этих??? родительских элементов
    Это Вы у меня спрашиваете или предлагаете определять вес этих элементов. Определить вес родительских эл-тов у меня не получилось, т.к. род. эл может иметь как в своем подчинении конечный элемент , так и неконечный.

    Вся проблема в том, что я не смог заставить скрипт делать следующее: если элемент не конечный (определяем это с помощью разницы правого и левого ключа) то у него значение будет - сумма произведений веса*значение подчиненных элементов, а если конечный, то указанное хначение. Скрипт не идет по ветке вниз, а останавливается на последующем уровне и принимает значения указанные в ячейках значений (независимо есть они там или их нет). Пробовал писать скрипт с условием: если у элемента значение "0", то его не принимать, а считать по алгоритму, указанному выше. Результат тот же.

    А по поводу статьи, то я ее читал не однократно, но все равно спасибо за ссылку.[/b]