Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: помогите разобраться в выводе данных из двух таблиц
 
 автор: куч1963   (11.03.2006 в 05:08)   письмо автору
 
 

На форуме неоднократно подымалась тема вывода данных из двух таблиц.
Все вопросы сводились к динамическому формированию меню. Хотелось бы получить небольшие разъяснения, так как совсем запутался в этом вопросе.

Имеются две таблицы:

menu id | name
categories id |name| id_m - внешний ключ формируемый по id из таблицы menu.
Хочется получить следующий результат:

name1(menu)
name1(categories)
name1(categories)
name1(categories)
name2(menu)
name2(categories)
name2(categories)
name2(categories) ну и т.д

Сделал запрос:

$query = "SELECT menu.id,
                 menu.name,
                 categories.id,
                 categories.name,
                 categories.id_m
          FROM menu INNER JOIN categories
          ON menu.id=categories.id_m
           GROUP BY menu.name
          ORDER BY menu.id"; 


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

   
 
 автор: cheops   (11.03.2006 в 12:13)   письмо автору
 
   для: куч1963   (11.03.2006 в 05:08)
 

Хм... а группировка разве не по categories.name должна быть?
$query = "SELECT menu.id, 
                 menu.name, 
                 categories.id, 
                 categories.name, 
                 categories.id_m 
          FROM menu INNER JOIN categories 
          ON menu.id=categories.id_m 
           GROUP BY menu.name 
          ORDER BY menu.id";

Про циклы что-то вообще не понятно... что требуется сделать? Имеются ввиду циклы в PHP?

   
 
 автор: куч1963   (12.03.2006 в 08:36)   письмо автору
 
   для: cheops   (11.03.2006 в 12:13)
 

Да, конечно, но вот только как обработать правильно этот запрос?


$query = "SELECT menu.id,
                 menu.name,
                 categories.id,
                 categories.name,
                 categories.id_m
          FROM menu INNER JOIN categories
          ON menu.id=categories.id_m
           GROUP BY categories.name
          ORDER BY menu.id";

$rez = mysql_query($query);

//я так понимаю, внешний цикл должен выводить результаты меню

while($menu = mysql_fetch_row($rez ))
      {         
         echo "<li>".$menu[1]."<br>";
  // внутренний результаты по категориям;
    
       while($categories = mysql_fetch_row($rez))
      {        
         echo "&nbsp;&nbsp;".$categories[3]."<br>";
          } 
       }


В итоге в результат вываливается название первого пункта таблицы menu, а спосле, результат работы внутреннего цикла, то есть, все содержимое таблицы categories :) ;
Так оно и должно быть, потому , что во второй цикл нужно вводить условие выборки, а как мне не понятно.
Если Вам не трудно, объясните пожалуйста.
Конечно, такие вопросы как у меня и многих мне подобных возникают из-за недостатка знаний и опыта програмирования. Часто даже не знаешь, как выразить умными словами то, что хочешь сделать. Может быть лезу с предложениями в чужой монастырь, но может есть смысл создать по наиболее частым вопросам раздел, типа уголок начинающего, где будут даваться общие принципы решения .

   
 
 автор: cheops   (12.03.2006 в 13:09)   письмо автору
 
   для: куч1963   (12.03.2006 в 08:36)
 

А нет, цикл должен быть один, но внутри цикла вы должны отслеживать в каком меню сейчас находитесь, примерно так
<?php
$query 
"SELECT menu.id AS id, 
                 menu.name AS name, 
                 categories.id, 
                 categories.name AS category, 
                 categories.id_m 
          FROM menu INNER JOIN categories 
          ON menu.id=categories.id_m 
           GROUP BY categories.name 
          ORDER BY menu.id"


$rez mysql_query($query); 

$name "";
while(
$menu mysql_fetch_row($rez )) 
{
  if(
$name != $menu['name'])
  {
    echo 
"<li>".$menu['name']."<br>";
    
$name $menu['name'];
  }
  echo 
"&nbsp;&nbsp;".$menu['category']."<br>"
}
?>

   
 
 автор: куч1963   (12.03.2006 в 13:26)   письмо автору
 
   для: cheops   (12.03.2006 в 13:09)
 

Скажите, а обязательно нужно переименовывать столбцы таблиц?



$name = "";
while($menu = mysql_fetch_row($rez ))
{
  if($name != $menu['name'])
  {
    echo "<li>".$menu['name']."<br>";
    $name = $menu['name'];
  }
  echo "&nbsp;&nbsp;".$menu['category']."<br>";



Вывод результатов идет правильно, только вот вопрос, почему не выводится в результат
все данные из таблицы меню, а выводятся те пункты, которым есть соответствие из таблицы categories?

   
 
 автор: elenaki   (12.03.2006 в 16:26)   письмо автору
 
   для: куч1963   (12.03.2006 в 13:26)
 

Вывод результатов идет правильно - ну так что еще надо, хороняка? ;)

я бы посоветовала новичку не париться с многотабличными запросами, а делать два запроса. сначала выбираем пункты меню из одной таблицы в цикле, потом соответствующие им пункты подменю из другой таблицы во втором, вложенном цикле.

   
 
 автор: куч1963   (12.03.2006 в 21:47)   письмо автору
 
   для: elenaki   (12.03.2006 в 16:26)
 

Всем большое спасибо за советы.

Вы советуете делать второй запрос к базе из цикла или как?

Тогда это очень оригинальное решение, и я обязательно им как нибудь воспользуюсь.:)

   
 
 автор: Trianon   (12.03.2006 в 21:53)   письмо автору
 
   для: куч1963   (12.03.2006 в 21:47)
 

Это очень дорогое решение, хотя бы потому, что придется в цикле дергать MySQL столько раз, сколько у Вас элементов меню, хотя можно этого избежать. Его плюсом являлась бы лишь относительная простота, и то лишь в том случае, если у Вас и вправду нет желания изучить, как пишутся многотабличные запросы. А меж тем, это очень полезное знание. Львиная доля SELECTов делается из INNER JOIN или их аналогов.

   
 
 автор: Trianon   (12.03.2006 в 17:44)   письмо автору
 
   для: куч1963   (12.03.2006 в 13:26)
 

Чтобы выводились элементы меню, в которых нет категорий, следует поменять тип соединения таблиц с внутреннего на левый внешний - поменять в запросе INNER JOIN на LEFT JOIN - после чего перед echo "&nbsp;&nbsp;".$menu['category']."<br>"; поставить условие if($menu['category'] != '').

if($menu['category'] != '')
echo "&nbsp;&nbsp;".$menu['category']."<br>";


Конструкция GROUP BY совершенно излишняя, т.к. с группами сервер БД не ведет никакой дополнительной обработки.

Кроме того, у меня пример не заработал, пока я mysql_fetch_row не заменил на mysql_fetch_array. В итоге:
<?php
$query 
"SELECT menu.id AS id,
                 menu.name AS name,
                 categories.id,
                 categories.name AS category,
                 categories.id_m
          FROM menu LEFT JOIN categories
          ON menu.id=categories.id_m
          ORDER BY menu.id"
;

$rez mysql_query($query);

$name "";

while(
$menu mysql_fetch_array($rez ))
{
  if(
$name != $menu['name'])
  {
    echo 
"<li>".$menu['name']."<br>";
    
$name $menu['name'];
  }
  if(
$menu['category'] != '')
    echo 
"&nbsp;&nbsp;".$menu['category']."<br>";
}
?>

   
 
 автор: elenaki   (12.03.2006 в 17:53)   письмо автору
 
   для: Trianon   (12.03.2006 в 17:44)
 

пока я mysql_fetch_row не заменил на mysql_fetch_array
=============================================
у меня тоже, кстати, на одном сервере работает fetch_row, на другом - нет. интересно, с чем это связано?

   
 
 автор: Trianon   (12.03.2006 в 18:09)   письмо автору
 
   для: elenaki   (12.03.2006 в 17:53)
 

Один и тот же код?! Странно.

Чтобы выяснить, почему так происходит, я бы написал так:

<?
echo '<pre>';
$resultmysql_query($query) or die "Error on $query <br> via:" mysql_error();
while(
$row mysql_fetch_row($result))
  
print_r($row);
?>
и внимательно поглядел вывод. На обоих серверах.

mysql_fetch_row возвращает массив значений полей, проиндексиованный номерами полей от 0 до n-1
mysql_fetch_array (без указания типа индексации) возвращает массив значений полей, проиндексиованный как номерами полей, так и их именами.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования