Как сделать запрос в базу и произвести затем выдачу

Sadalsky

Новичок
Существуют две таблицы menu и data:

Таблица menu:
id_menu parent_menu title

1 0 Овощи
2 0 Фрукты
3 1 Овощи Русские
4 1 Овощи Буржуйские
5 2 Фрукты Русские
6 2 Фрукты Буржуйские
7 3 Чистые
8 3 Грязные
9 4 Чистые
10 4 Грязные
11 5 Чистые
12 5 Грязные
13 6 Чистые
14 6 Грязные

где id_menu - уникальный индификатор категории, parent_menu - ссылка на родительский элемент,title-название категории

Таблица data:

id_data parent_data title_data
1 7 Картофель Русский Чистый
2 7 Морковь Русский Чистый
3 8 Картофель Русский Грязный
4 8 Морковь Русский Грязный
5 9 Картофель Буржуйский Чистый
6 9 Морковь Буржуйский Чистый
7 10 Картофель Буржуйский Грязный
8 10 Морковь Буржуйский Грязный

где parent_data - ссылка на родительский элемент.

Задача: Существует сайт типа:блог и начинающий сайтостроитель. Слева на странице, как положено, выводится меню в виде дерева, а вот справа выводится контент...При выборе пункта menu происходит передача данных id_menu... и здесь самое непонятное...Как нужно сделать запрос к базе, потом загнать в массив и уже после этого зациклить, при условии что при выборе в таблице menu родительской категории - из таблицы data выводились не только те элементы, которые непосредственно относятся к самой категории, но и из подкатегорий этого родителя(Грубо говоря, на каждом шаге должна существовать выдача...).

Пример: В таблице menu выбираем Овощи Русские(id_menu=3) и из data получаем:

Картофель Русский Чистый(id_data=1)
Морковь Русский Чистый(id_data=2)
Картофель Русский Грязный(id_data=3)
Морковь Русский Грязный(id_data=4)

Заранее премного благодарен всем откликнувшимся!!!
 

HEm

Сетевой бобер
ты смешал несколько характеристик в одну таблицу, это неправильно либо должна быть другая схема связей

"В таблице menu выбираем Овощи Русские(id_menu=3) и из data получаем" - ничего не получим, нет у нас овощей с родителем под номером 3
 

Sadalsky

Новичок
ты смешал несколько характеристик в одну таблицу, это неправильно либо должна быть другая схема связей

"В таблице menu выбираем Овощи Русские(id_menu=3) и из data получаем" - ничего не получим, нет у нас овощей с родителем под номером 3

короче говоря....предложили вот такой кодинг...только я не пойму...как его притянуть..
PHP:
// $id_ctg - уникальный ID той категории (раздела каталога) для которой 
// мы выводим список все товаров (и в том числе товаров в подкатегориях)
$ctgs = get_subcategories( $id_ctg );
$ctgs[] = $id_ctg;
$ids = implode($ctgs);
$query = "SELECT * FROM `products` WHERE `id_ctg` IN (".$ids.") ORDER BY price";
 
// Получить для текущей категории все подкатегории (всех уровней вложенности)
function get_subcategories( $id )
{
  $q = mysql_query("SELECT `id_ctg` FROM `categories` WHERE `parent`=".$id);
  $r = array();
  while ($row = mysql_fetch_row($q)) {
    $r[] = $row[0];
    $a = get_subcategories( $row[0] );
    for ( $i = 0; $i < count($a); $i++ ) $r[] = $a[$i];
  }
  return $r;
}
 

HEm

Сетевой бобер
На этом форуме в вашем случае этот совет самый дельный. Если ктото еще читает эту ветку он подтвердит это, поставив на мое сообщение лайк ;)

Здесь никто не будет решать ваши проблемы, если вы чтото делаете и у вас не получается - вам подскажут, куда надо думать, но думать за вас не будут. Либо вы развиваетесь, либо с проклятиями покидаете этот сайт и ищете место, где вам дадут рыбу (если непонятна фраза - тыц)
 

Sadalsky

Новичок
Так я и пришел сюда для того, чтобы услышать совет, а не получить готовое решение. Перелопатил огромное количество информации по рекурсии и всяких там netset...только толку 0. И после того, как совсем отчаялся, решил посоветоваться....У меня изначально была мысль разбивать всё на несколько таблиц(т.е. более двух), но когда начал строить дерево меню, обнаружил, что таких таблиц должно быть две, например:categories и products. Начал ковыряться дальше и тут мозг закипел....Мы все когда то с чего то начинали и не надо забывать про это...
 

HEm

Сетевой бобер
ок, продолжим с начала, спасибо, что не обиделись на обидные слова

Несмотря на то что и при такой структуре можно вытаскивать данные как нужно, я думаю, проблема в первую очередь в том, как вы организовали меню (это в самом деле меню или это вам так удобно называть дерево?). Как я сразу и сказал, в меню у вас смешаны абсолютно разные характеристики, причем чем ниже категория тем больше они дублируются, это неправильно. Признак чистый/грязный должен стоять в характеристиках продукта, а не в категории меню. Если нужно выбрать по характеристикам (а это уже практически поиск по каталогу), то для этого используется не дерево-меню, а форма с чекбоксами/селектами/радиокнопками.

Если все же вы настаиваете на том чтобы не менять таблицы то я бы сделал во второй таблице отдельное поле cat_path со значениями в духе "/1/3/7/" (пересобирается при добавлении/изменении товара) и при необходимости например найти русские овощи делал бы запрос вида
PHP:
SELECT * FROM data AS d WHERE d.path LIKE '%/3/%'
 

HEm

Сетевой бобер
как нетрудно увидеть при желании найти просто чистые овощи уже возникает ад и запрос приобретает вид
PHP:
SELECT * FROM data AS d INNER JOIN menu AS m ON d.path LIKE CONCAT('%/',m.id,'/%') WHERE m.title="Чистые"
, я даже не уверен, что такой запрос сработает
 

Sadalsky

Новичок
Спасибо и вам за понимание!!! Я действительно с данной задачкой зашел в тупик....
 

Sadalsky

Новичок
Вот так сформировано меню, я думаю что это дерево...Если не так поправьте меня. От него я и толкаюсь... Оно подсажено на jquery скрипт - jquery.treeview.js.
PHP:
<?php
$parts_query = mysql_query("SELECT id_menu, parent_menu, name_menu FROM menu
", $db);

if ($parts_query && mysql_num_rows($parts_query) > 0) {
  $parts_array = array();
  $part_data = 0;
  while($part_data = mysql_fetch_row($parts_query)) {
    $part_data[1] = isset($part_data[1]) && $part_data[1] > 0 ?
$part_data[1] : 0;
    array_push($parts_array, $part_data);
  }
  mysql_free_result($parts_query);
}

  $this_count = 0;
  foreach ($parts_array as $idx => $element) {
   
    if ($element[1] == $parent_menu) {
      $this_count++;
      
      if ($this_count == 1) {
  if ($parent_menu == 0 ) 
    echo '<ul id="menu">';
  else
    echo '<ul>'; }
      echo("<li class='closed'><a
href=\"view_menu.php?id_menu=".$element[0]."\">".$element[2]."</a>"); 
     
      get_hierarchy($parts_array, $element[0]);
      echo("</li>");
    }
  }
  if ($this_count > 0)
    echo("</ul>");
}

echo(get_hierarchy($parts_array, 0));
?>
 

fixxxer

К.О.
Партнер клуба
Начните с приведения кода в нормальный вид.
Код:
          очень
 сложно                     читать 
                 код 
                              с
отступами                          расставленными
    генератором
                                                     случайных
чисел.
 

Sadalsky

Новичок
Да в таблице надо смешивать абсолютно разные характеристики. Пример: Страна - Город - Рестораны или Страна - Город - Гостиницы и здесь мне всё же хотелось бы использовать не радиокнопки, а именно такую менюшку....
 

HEm

Сетевой бобер
offtopic:
забавно форум считает время постинга ;)
"fixxxer, секунду назад" - это я увидел сообщение от qip, тыкнул в первую вкладку в опере с настроенной под меня домашней страницей с кучей ссылок, тыкнул в Gmail, дождался открытия письма, кликнул в ссылку
 

Sadalsky

Новичок
Хорошо. А, если так...:
PHP:
<?php #Дерево разделов.
#Выбор _всех_ разделов.
$parts_query = mysql_query("SELECT id_menu, parent_menu, name_menu FROM menu
", $db);
#Если есть хоть какие-то разделы.
if ($parts_query && mysql_num_rows($parts_query) > 0) {
  $parts_array = array();
  $part_data = 0;
  #Распихиваем полученные данные в массив.
  #Попутно для красоты заменяем возможные пустые поля
  #(для разделов, не имеющих родителя) на ноль.
  while($part_data = mysql_fetch_row($parts_query)) {
    $part_data[1] = isset($part_data[1]) && $part_data[1] > 0 ?
$part_data[1] : 0;
    array_push($parts_array, $part_data);
  }
  mysql_free_result($parts_query);
}
#Это функция, рекурсивно вызывающаяся для формирования дерева разделов.
#Кол-во записей на текущем уровне. Нужно для того, чтобы
#выводить <ul>...</ul> для этого уровня, т.е. если записей нет, то и
#эти тэги не нужны.
  $this_count = 0;
  foreach ($parts_array as $idx => $element) {
    #Выводим раздел текущего уровня (тот, чей идентификатор родителя
    #равен заданному при вызове функции
    if ($element[1] == $parent_menu) {
      $this_count++;
      #Вывод HTML очередного пункта меню.
      if ($this_count == 1) {
  if ($parent_menu == 0 ) 
    echo '<ul id="menu">';
  else
    echo '<ul>'; }
      echo("<li class='closed'><a
href=\"view_menu.php?id_menu=".$element[0]."\">".$element[2]."</a>"); 
      #функция вызывает саму себя для формирования
      #дочерних узлов текущего раздела.
      get_hierarchy($parts_array, $element[0]);
      echo("</li>");
    }
  }
  if ($this_count > 0)
    echo("</ul>");
}
#Начальный вызов: идентификатор родительского раздела равен
#нулю, т.е. "родителя нет".
echo(get_hierarchy($parts_array, 0));
?>
 

HEm

Сетевой бобер
ключевое слово "отступы"
PHP:
      if ($this_count == 1) {
  if ($parent_menu == 0 )
так нельзя, проследить логику становится очень трудно
 

Sadalsky

Новичок
Переписать? Вы уж простите меня, люд добрый, впервые на форумах....
 

HEm

Сетевой бобер
вы все таки не программист

если логическая конструкция находится внутри другой, то отступов слева у нее должно быть больше
 

Sadalsky

Новичок
Так?

PHP:
<?php 
#Дерево разделов.
#Выбор _всех_ разделов.
$parts_query = mysql_query("SELECT id_menu, parent_menu, name_menu FROM menu", $db);
#Если есть хоть какие-то разделы.
if ($parts_query && mysql_num_rows($parts_query) > 0) {
         $parts_array = array();
         $part_data = 0;
  #Распихиваем полученные данные в массив.
  #Попутно для красоты заменяем возможные пустые поля
  #(для разделов, не имеющих родителя) на ноль.
           while($part_data = mysql_fetch_row($parts_query)) {
                     $part_data[1] = isset($part_data[1]) && $part_data[1] > 0 ?
                     $part_data[1] : 0;
                     array_push($parts_array, $part_data);
                     mysql_free_result($parts_query);
                     }
#Это функция, рекурсивно вызывающаяся для формирования дерева разделов.
#Кол-во записей на текущем уровне. Нужно для того, чтобы
#выводить <ul>...</ul> для этого уровня, т.е. если записей нет, то и
#эти тэги не нужны.
  $this_count = 0;
  foreach ($parts_array as $idx => $element) {
    #Выводим раздел текущего уровня (тот, чей идентификатор родителя
    #равен заданному при вызове функции
           if ($element[1] == $parent_menu) {
                 $this_count++;
      #Вывод HTML очередного пункта меню.
                     if ($this_count == 1) {
                         if ($parent_menu == 0 ) 
                            echo '<ul id="menu">';
                    else  echo '<ul>'; }
                              echo("<li class='closed'><a href=\"view_menu.php?id_menu=".$element[0]."\">".$element[2]."</a>"); 
      #функция вызывает саму себя для формирования
      #дочерних узлов текущего раздела.
      get_hierarchy($parts_array, $element[0]);
      echo("</li>");
    }
  }
  if ($this_count > 0)
    echo("</ul>");
}
#Начальный вызов: идентификатор родительского раздела равен
#нулю, т.е. "родителя нет".
echo(get_hierarchy($parts_array, 0));
?>
 
Сверху