Вывод части дерева согласно условию по связанной таблице

ACherry

Новичок
Вывод части дерева согласно условию по связанной таблице

Многоуважаемые! Помогите плз. не хватает сил осмыслить как это реализовать :(

Есть каталог с вложенными "неограниченно" разделами
В конечном разделе есть позиции товаров которые через промежуточную таблицу связаны с поставщиками
Задача на первый взгляд простая: вывести только те части "дерева" на конечной ветви которых есть разделы с товарами от конкретного поставщика

вот что пока получилось:
PHP:
   function get_data () 
    {           
        $query = "SELECT cat.name, cat_linear.cid, cat.parent, cat.cid FROM cat_linear, cat WHERE cat.cid=cat_linear.cid  ORDER by cat_linear.name;"; 
        $res = mysql_query ($query); 
         
        $data = array (); 
        while ($row = mysql_fetch_assoc ($res)) 
        {                             
            $data [] = $row; 
        }   
        return $data; 
    }          


    function print_three ($data, $parent) 
    { 
        static $counter = 0; 
         
        $counter += 5; 
        for ($i = 0; $i < count ($data); $i ++) 
        { 
            if ($data [$i] ['parent'] == $parent) 
            { 
                for ($j = 0; $j < $counter; $j ++)

                    echo "<IMG height=1 src=/img/blank.gif width=3 border=0>"; 

$pid=$_GET['pid']; .// ID нужного поставщика
$cid=$data [$i] ['cid']; // ID раздела
$rescount = mysql_result(mysql_query("SELECT count(cat_main.lid) FROM cat_main INNER JOIN cat_firm ON cat_firm.cat_lid=cat_main.lid WHERE cat_firm.cat_id='$pid' AND cat_main.type=1 AND cat_main.cat1='$cid'"),0,0);
// количество в конечном разделе от конкретного поставщика


$cntr= "[". $rescount . "]";
                echo "<font style=\"font-size:9;\">&bull;</font><a style=\"color:".$color.";\"  href=./res_one.php?c=" . $data [$i] ['cid'] . "&pid=".$_GET['pid'].">" . preg_replace("/[0-9]/","",$data [$i] ['name'], 3)  . "</a> <font color=gray>" . $cntr . "</font><br>"; 

                print_three ($data, $data [$i] ['cid']); 
            } 
        } 
        $counter -= 5; 
    } 
    $d = get_data (); 
    print_three ($d,$cid);
выводит все дерево и считает кол-во удовлетворяющих позиций в разделах

на выходе сейчас имеем все дерево в таком виде:

• системы вентиляции, кондиционирования, отопления [0]
- • системы кондиционирования [0]
- • системы вентиляции [0]
- • системы отопления [0]
• холодильные и морозильные камеры, склады, помещения [0]
- • холодильные камеры [0]
- - • объем до 6 м.куб. [15]
- - • объем до 12 м.куб. [9]
- - • объем до 18 м.куб. [9]
- - • объем до 24 м.куб. [7]
- - • объем до 50 м.куб. [0]
- • холодильные склады [5]

а хотелось вот так:

-- пустой раздел не выводим
• холодильные и морозильные камеры, склады, помещения [45]
- • холодильные камеры [40]
- - • объем до 6 м.куб. [15]
- - • объем до 12 м.куб. [9]
- - • объем до 18 м.куб. [9]
- - • объем до 24 м.куб. [7]
- • холодильные склады [5]

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

просьба сильно не пинать, мозг просто уже не воспринимает адекватно мануалы :(
 

vovanium

Новичок
Имхо, нуна делать так:
- добавляешь в таблицу инфу о всех родителях, т.е. простое текстовое поле где через запятую перечислены все родительские разделы до корня.
- потом делаешь запрос по нужному производителю с группировкой по cat_id
- получаешь все разделы в которых есть нужные товары
- у тебя есть инфа о всех нужных родителях, парсишь их убираешь дубликаты, после чего выбираешь нужную инфу о родителях из базы, прописывая сколько в них есть продуктов
- после чего уже по получившемуся массиву строишь дерево.

Что касается твоего алгоритма, то нужно сначала достать всю инфу, а в print_tree вместо вывода дерева, возвращать количество товаров для данного pid'а. А потом уже вторым этапом, по массиву в котором уже прописано количество товаров в каждом разделе, рисовать дерево.
 

ACherry

Новичок
Немного переделал. Работает быстрее. Но не работает как надо :) Вносить изменения в структуру очень не хочется...

В общем, осталась одна проблема: как сложить значения количества товаров (ф-я ChgCountR) для родительских ветвей и соотв. не показывать ветви где таких товаров нет совсем.

PHP:
// ф-я подсчета товаров
function ChgCountR($cid,$pid) {
	do {
		$q=mysql_result(mysql_query("SELECT count(cat_main.lid) FROM cat_main 
INNER JOIN cat_firm ON cat_firm.cat_lid=cat_main.lid 
WHERE cat_firm.cat_id='$pid' AND cat_main.type=1 AND cat_main.cat1='$cid'"),0,0);
		
		$count+= $q;

		$r=mysql_query("SELECT parent FROM cat
WHERE cid='$cid' AND count > 0;") or die(mysql_error());
		if (mysql_num_rows($r)==1) $cid=mysql_result($r,0,0);
			} while ($cid!=0);
				return $count;	}
// конец ф-ии подсчета

// выбираем дерево 
	$query = "SELECT cat.cid,  cat.parent, cat.name FROM  cat WHERE cat.count > 0 ORDER by cat.name"; 
	$res = mysql_query ($query);
			while($row = mysql_fetch_assoc($res)){
				$tree[$row['parent']][$row['cid']] = $row['name'];
																}

// print_r($tree); // проверяем что в массиве

	function ShowTree($tree, $cid){
		echo "<ul type='square'>";
			foreach($tree as $id=>$root){
				if($cid!=$id)continue;
					if(count($root)){
						foreach($root as $key => $name){

$rescount = ChgCountR($key,$_GET['pid']); // вызываем ф-ю подсчета
$cntr= "[". $rescount . "]"; // рисуем счетчик

						// делаем ссылку с счетчиком, убираем цифры из наименования разделов
						echo "<li><a style=\"color:blue;\"  href=./res_one.php?c={$key}&pid=".$_GET['pid'].">" . preg_replace("/[0-9]/","",$name, 3)  . "</a> <font color=gray>" . $cntr . "</font>";

// Именно во втором цикле надо вызывать рекурсию, для чего сначала проверим, а есть ли потомки с таким родителем
								if(count($tree[$key]))ShowTree($tree,$key);
          	}
					}
				}
			echo "</ul>";
		}

// выводим дерево
ShowTree ($tree,  $cid);
не могу понять в каком месте накосясил... Помогите криворукому :) Мануалы читал но ничего не понял, наверно не судьба...
 
Сверху