|
|
|
| На форуме неоднократно подымалась тема вывода данных из двух таблиц.
Все вопросы сводились к динамическому формированию меню. Хотелось бы получить небольшие разъяснения, так как совсем запутался в этом вопросе.
Имеются две таблицы:
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";
|
Не знаю, насколько он соответствует данной задаче, а вот с организацией циклов вообще запара. Как правильно организовать внешний и внутренний циклы выборки для решения данной задачи?
Пожалуйста помогите разобраться. Как вообще организовывается работа по данным из связанных таблиц | |
|
|
|
|
|
|
|
для: куч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? | |
|
|
|
|
|
|
|
для: 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 " ".$categories[3]."<br>";
}
}
|
В итоге в результат вываливается название первого пункта таблицы menu, а спосле, результат работы внутреннего цикла, то есть, все содержимое таблицы categories :) ;
Так оно и должно быть, потому , что во второй цикл нужно вводить условие выборки, а как мне не понятно.
Если Вам не трудно, объясните пожалуйста.
Конечно, такие вопросы как у меня и многих мне подобных возникают из-за недостатка знаний и опыта програмирования. Часто даже не знаешь, как выразить умными словами то, что хочешь сделать. Может быть лезу с предложениями в чужой монастырь, но может есть смысл создать по наиболее частым вопросам раздел, типа уголок начинающего, где будут даваться общие принципы решения . | |
|
|
|
|
|
|
|
для: куч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 " ".$menu['category']."<br>";
}
?>
|
| |
|
|
|
|
|
|
|
для: 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 " ".$menu['category']."<br>";
}
|
Вывод результатов идет правильно, только вот вопрос, почему не выводится в результат
все данные из таблицы меню, а выводятся те пункты, которым есть соответствие из таблицы categories? | |
|
|
|
|
|
|
|
для: куч1963
(12.03.2006 в 13:26)
| | Вывод результатов идет правильно - ну так что еще надо, хороняка? ;)
я бы посоветовала новичку не париться с многотабличными запросами, а делать два запроса. сначала выбираем пункты меню из одной таблицы в цикле, потом соответствующие им пункты подменю из другой таблицы во втором, вложенном цикле. | |
|
|
|
|
|
|
|
для: elenaki
(12.03.2006 в 16:26)
| | Всем большое спасибо за советы.
Вы советуете делать второй запрос к базе из цикла или как?
Тогда это очень оригинальное решение, и я обязательно им как нибудь воспользуюсь.:) | |
|
|
|
|
|
|
|
для: куч1963
(12.03.2006 в 21:47)
| | Это очень дорогое решение, хотя бы потому, что придется в цикле дергать MySQL столько раз, сколько у Вас элементов меню, хотя можно этого избежать. Его плюсом являлась бы лишь относительная простота, и то лишь в том случае, если у Вас и вправду нет желания изучить, как пишутся многотабличные запросы. А меж тем, это очень полезное знание. Львиная доля SELECTов делается из INNER JOIN или их аналогов. | |
|
|
|
|
|
|
|
для: куч1963
(12.03.2006 в 13:26)
| | Чтобы выводились элементы меню, в которых нет категорий, следует поменять тип соединения таблиц с внутреннего на левый внешний - поменять в запросе INNER JOIN на LEFT JOIN - после чего перед echo " ".$menu['category']."<br>"; поставить условие if($menu['category'] != '').
if($menu['category'] != '')
echo " ".$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 " ".$menu['category']."<br>";
}
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(12.03.2006 в 17:44)
| | пока я mysql_fetch_row не заменил на mysql_fetch_array
=============================================
у меня тоже, кстати, на одном сервере работает fetch_row, на другом - нет. интересно, с чем это связано? | |
|
|
|
|
|
|
|
для: elenaki
(12.03.2006 в 17:53)
| | Один и тот же код?! Странно.
Чтобы выяснить, почему так происходит, я бы написал так:
<?
echo '<pre>';
$result= mysql_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 (без указания типа индексации) возвращает массив значений полей, проиндексиованный как номерами полей, так и их именами. | |
|
|
|