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

Форум MySQL

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

 

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

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

тема: Выборка из двух таблиц
 
 автор: gOFREe   (15.07.2009 в 21:32)   письмо автору
 
 

Я уже читал тут на форуме, но что то сам никак не могу сообразить, точнее могу, но у меня получается коряво, хотелось бы по грамотней, значит так, есть две таблицы
menu и menuR
menu
_______________________
id | menu_name | menu_link |
1 | Сайт | # |
----------------------------------------|
2 | Категории | # |
-----------------------------------------
menuR
_______________________
idr | menu_nameR | menu_linkR |
1 | О сайте | # |
---------------------------------------------|
2 | категория1 | # |
---------------------------------------------|
2 | категория2 | # |
---------------------------------------------|
2 | категория3 | # |
---------------------------------------------
Как сделать правильную выборку? пробовал через LEFT JOIN и вывод идет такой: сколько подкатегорий, столько он выводит и категорий. Пробовал делать запрос ко второй таблице в цикле первого запроса, но это слишком коряво, очень много запросов к базе.
Спасибо!

  Ответить  
 
 автор: Trianon   (15.07.2009 в 22:31)   письмо автору
 
   для: gOFREe   (15.07.2009 в 21:32)
 

сколько строк в результирующей таблице Вы хотите получить? И какие?

  Ответить  
 
 автор: gOFREe   (15.07.2009 в 23:01)   письмо автору
 
   для: gOFREe   (15.07.2009 в 21:32)
 

Должно быть так:

+Сайт
-О сайте

+Категории
-категория1
-категория2
-категория3
Мои попытки

<?
$sql 
"SELECT menu.*,menuR.* FROM menu LEFT JOIN menuR ON menuR.idr = menu.id";
?>

  Ответить  
 
 автор: Trianon   (15.07.2009 в 23:43)   письмо автору
 
   для: gOFREe   (15.07.2009 в 23:01)
 

Мой вопрос неясен?

  Ответить  
 
 автор: gOFREe   (16.07.2009 в 00:11)   письмо автору
 
   для: Trianon   (15.07.2009 в 23:43)
 

Честно... нет ... сорри, еще учусь )

  Ответить  
 
 автор: Trianon   (16.07.2009 в 00:16)   письмо автору
 
   для: gOFREe   (16.07.2009 в 00:11)
 

Я спросил не как должен выглядеть результат на экране посетителя.
Я спросил, чего Вы ожидаете от запроса. Точнее от SQL-сервера, который этот запрос исполняет.
Сервер в ответ на SELECT-запрос обязан выдать таблицу.
Ровненькую такую таблицу и ничего более.

  Ответить  
 
 автор: gOFREe   (16.07.2009 в 10:46)   письмо автору
 
   для: Trianon   (16.07.2009 в 00:16)
 

SELECT должен вывести, желательно в одном запросе, все строки из двух таблиц, но не больше.

  Ответить  
 
 автор: Trianon   (16.07.2009 в 11:33)   письмо автору
 
   для: gOFREe   (16.07.2009 в 10:46)
 

Для приведеного Вами примера входящих таблиц, как должен выглядеть результат SELECTа?

Я почему спрашиваю: LEFT JOIN - идеальное решение для Вашего случая. Но оно почему-то Вас не устраивает. Вот и пытаюсь выяснить, какой результат ( от запроса) ждете Вы.

  Ответить  
 
 автор: gOFREe   (16.07.2009 в 11:47)   письмо автору
 
   для: Trianon   (16.07.2009 в 11:33)
 

Оно меня устраивает, если бы он вывел результат правильно, а он выводит результат не полностью. А только столько, на сколько хватает цикла при выводе, насколько я понял... Как посчитать все строки двух таблиц?

  Ответить  
 
 автор: Trianon   (16.07.2009 в 11:52)   письмо автору
 
   для: gOFREe   (16.07.2009 в 11:47)
 

как должен выглядеть результат SELECTа с Вашей точки зрения?

C моей:

menu_name | menu_nameR
----------+-----------
Сайт      | О сайте
Категории | категория1
Категории | категория2
Категории | категория3

А с Вашей?

  Ответить  
 
 автор: gOFREe   (16.07.2009 в 11:55)   письмо автору
 
   для: Trianon   (16.07.2009 в 11:52)
 


menu_name | menu_nameR
----------+-----------
Сайт      | О сайте
Категории | категория1
--------- | категория2
--------- | категория3

  Ответить  
 
 автор: Trianon   (16.07.2009 в 13:25)   письмо автору
 
   для: gOFREe   (16.07.2009 в 11:55)
 

А чем категория2 и категория3 провинились?
Ту нормализацию, которую Вы пытаетесь показать, должен делать не SQL , а php-код.
http://softtime.ru/forum/read.php?id_forum=3&id_theme=65652

  Ответить  
 
 автор: gOFREe   (16.07.2009 в 15:05)   письмо автору
 
   для: Trianon   (16.07.2009 в 13:25)
 

Делайю так, все равно не получается, из menuR выводит так:

menu_name | menu_nameR
----------+-----------
Сайт      | О сайте
Категории | категория1
--------- |---------
--------- | ---------

а вот категория2 и категория3 не хотят вылазить :((
<?
$sql 
"SELECT menu.*,menuR.* FROM menu LEFT JOIN menuR ON menuR.idr = menu.id";
$res mysql_query($sql); 
if(!
$res) exit("Error in $sql: "mysql_error());
$rows=mysql_num_rows($res);
$name="";
for (
$i=0$i<$rows$i++)  
           {  
 
$menumysql_fetch_array($res);  
if (
$name !=  $menu[menu_name])
     {
echo 
$menu[menu_name];
$name $menu[menu_name];
     }
echo 
$menu[menu_nameR];
          }
?>

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 01:32)   письмо автору
 
   для: gOFREe   (16.07.2009 в 15:05)
 

Подскажите люди добрые :)

  Ответить  
 
 автор: Trianon   (17.07.2009 в 01:39)   письмо автору
 
   для: gOFREe   (17.07.2009 в 01:32)
 

последний код написан крайне неряшливо, но в целом грубых ошибок в логике не содержит (содержит только ошибки синтаксиса и безобразно оформлен стилистически), так что по идее должен делать вид, что работает.
попробуйте эти самые ошибки устранить.
К примеру $menu[menu_name] писать нехорошо.

  Ответить  
 
 автор: ride   (17.07.2009 в 08:27)   письмо автору
 
   для: gOFREe   (17.07.2009 в 01:32)
 

+ добавьте order by

  Ответить  
 
 автор: Trianon   (17.07.2009 в 08:41)   письмо автору
 
   для: ride   (17.07.2009 в 08:27)
 

верно, требуется ORDER BY по ключу левой таблицы.

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 11:24)   письмо автору
 
   для: Trianon   (17.07.2009 в 08:41)
 

Все равно не хочет выводить категорию2 и категорию3

  Ответить  
 
 автор: Trianon   (17.07.2009 в 12:54)   письмо автору
 
   для: gOFREe   (17.07.2009 в 11:24)
 

дамп в студию.

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 13:19)   письмо автору
 
   для: Trianon   (17.07.2009 в 12:54)
 

В файле у меня так

<?
include_once('config.php');
@
mysql_connect($server_name$user_name$db_pass)
or die(
'Невозможно соедениться с БД');
@
mysql_select_db($db_name) or die('Невозможно найти БД'); 
$sql =  "SELECT menu.*, menuR.*
                 FROM menu
                 LEFT JOIN menuR
                 ON menuR.idr = menu.id ORDER by menu.id"

$res mysql_query($sql); 
$name ""
$header "";
   while( 
$i_menu dbarray($res) ) {
       
$header .= "<ul id='nav-one' class='nav'>";
       if(
$name != $i_menu['menu_name']) {
           
$header .= "<li><a  href='".$i_menu['menu_link']."'>".$i_menu['menu_name']."</a>";
           
$name $i_menu['menu_name'];
           }
           if (
$i_menu['menu_linkR'] != '') {
               
$header .= "<ul><li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li></ul>";
               }
               
$header .= "</li></ul>";
               }
?>

потом уже переменная $header выводится в index.php, может все из за этого?

  Ответить  
 
 автор: Trianon   (17.07.2009 в 13:23)   письмо автору
 
   для: gOFREe   (17.07.2009 в 13:19)
 

>В файле у меня так
при чем тут файл? я про дамп спросил.
Дамп это последовательность операторов CREATE TABLE и INSERT

Файл же Ваш по большому счету - вообще объект головной боли раздела PHP (а не MySQL)

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 13:33)   письмо автору
 
   для: Trianon   (17.07.2009 в 13:23)
 

Ну туплю )))
На префиксы не обращаем внимания

--
-- Структура таблицы `tun_menu`
--

CREATE TABLE IF NOT EXISTS `tun_menu` (
  `id` tinyint(4) NOT NULL auto_increment,
  `posid` varchar(255) NOT NULL default '',
  `menu_name` varchar(255) NOT NULL default '',
  `menu_link` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  KEY `id_2` (`id`),
  KEY `id_3` (`id`),
  KEY `posid` (`posid`),
  KEY `menu_name` (`menu_name`),
  KEY `menu_link` (`menu_link`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=3 ;

--
-- Дамп данных таблицы `tun_menu`
--

INSERT INTO `tun_menu` (`id`, `posid`, `menu_name`, `menu_link`) VALUES
(1, '1', 'Главная', '/'),
(2, '2', 'Сайт', '#');

--
-- Структура таблицы `tun_menuR`
--

CREATE TABLE IF NOT EXISTS `tun_menuR` (
  `id` tinyint(4) NOT NULL auto_increment,
  `idr` tinyint(4) NOT NULL,
  `menu_nameR` varchar(255) NOT NULL default '',
  `menu_linkR` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  KEY `id_2` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=4 ;

--
-- Дамп данных таблицы `tun_menuR`
--

INSERT INTO `tun_menuR` (`id`, `idr`, `menu_nameR`, `menu_linkR`) VALUES
(1, 2, 'Регистрация', '/register'),
(2, 2, 'О нас', '/about'),
(3, 1, 'TECT', '/test');

  Ответить  
 
 автор: Trianon   (17.07.2009 в 13:50)   письмо автору
3.9 Кб
 
   для: gOFREe   (17.07.2009 в 13:33)
 

не знаю, что у Вас там не идет.
У меня - см. аттач.

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 17:06)   письмо автору
 
   для: Trianon   (17.07.2009 в 13:50)
 

Да, точно, все работает, просто я стормозил...
У меня еще вопрос. Как сделать что бы теги <ul> и </ul> при выводе подкатегорий , выводились только в начале и в конце всего вывода.
т.е. не так:

//цикл
<ul><li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li></ul>
<ul><li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li></ul>
<ul><li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li></ul>

а вот так

//цикл
<ul>
<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>
<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>
<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>
</ul>

Это уже к PHP но все же... Спасибо

  Ответить  
 
 автор: Trianon   (17.07.2009 в 17:18)   письмо автору
 
   для: gOFREe   (17.07.2009 в 17:06)
 

str_replace

  Ответить  
 
 автор: ride   (17.07.2009 в 17:34)   письмо автору
 
   для: gOFREe   (17.07.2009 в 17:06)
 

 while( $i_menu = dbarray($res) ) {
       $header .= "<ul id='nav-one' class='nav'>";
       if($name != $i_menu['menu_name']) {
           $header .= "<li><a  href='".$i_menu['menu_link']."'>".$i_menu['menu_name']."</a><ul>";
           $name = $i_menu['menu_name'];
           }
           if ($i_menu['menu_linkR'] != '') {
               $header .= "<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>";
               }
               $header .= "</ul></li></ul>";
               } 

  Ответить  
 
 автор: gOFREe   (17.07.2009 в 21:34)   письмо автору
 
   для: ride   (17.07.2009 в 17:34)
 

А смысл? :) Цикл есть цикл.

  Ответить  
 
 автор: ride   (17.07.2009 в 21:44)   письмо автору
 
   для: gOFREe   (17.07.2009 в 21:34)
 

я конечно не проверял, но, как мне кажется, на ваш вопрос
У меня еще вопрос. Как сделать что бы теги <ul> и </ul> при выводе подкатегорий , выводились только в начале и в конце всего вывода.


ответил.
только я бы изменил немного - примерно так
$header= "<ul id='nav-one' class='nav'>"; $name='';
while( $i_menu = dbarray($res) ) {
       if($name != $i_menu['menu_name']) {
           if($name!=='')$header .= '</ul></li>';
           $header .= "<li><a  href='".$i_menu['menu_link']."'>".$i_menu['menu_name']."</a><ul>";
           $name = $i_menu['menu_name'];
           }
           if ($i_menu['menu_linkR'] != '') {
               $header .= "<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>";
               }
               }
$header .= "</ul></li></ul>"; 

и должно получиться
<ul>
    <li>
           Категория 1<ul><li>покатегория 1_1</li><li>покатегория 1_2</li></ul>
   </li>
    <li>
           Категория 2<ul><li>покатегория 2_1</li><li>покатегория 2_2</li></ul>
   </li>
</ul>

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 17:06)   письмо автору
 
   для: ride   (17.07.2009 в 21:44)
 

Учитывая эту строку: $header .= "</ul></li></ul>"; то она вынесена за цикл, а значит отобразится только один раз, в конце этого самого цикла. Уже не получается... :((

  Ответить  
 
 автор: ride   (19.07.2009 в 17:20)   письмо автору
 
   для: gOFREe   (19.07.2009 в 17:06)
 

вы проверяли?

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 17:46)   письмо автору
 
   для: ride   (19.07.2009 в 17:20)
 

Да

  Ответить  
 
 автор: ride   (19.07.2009 в 17:52)   письмо автору
 
   для: gOFREe   (19.07.2009 в 17:46)
 

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

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 18:28)   письмо автору
 
   для: ride   (19.07.2009 в 17:52)
 

Конечно, вот

<ul id='nav-one' class='nav'>
<li> <a  href='/'>Категория</a>
<ul>
     <li><a  href='/cat1'>категория1</a>
<ul>
     <li><a  href='/cat11'>категория2</a>
<ul>
     <li><a  href='/cat1'>ПОДКАТЕГОРИЯ1</a></li>
<li><a  href='/cat111'>категория3</a>

<ul>
    <li><a  href='#'>категория4</a>
<ul>
    <li><a  href='/cat2'>ПОДКАТЕГОРИЯ2</a></li>
<li><a  href='/cat3>ПОДКАТЕГОРИЯ3</a></li>
</ul>
</li>
</ul>

  Ответить  
 
 автор: ride   (19.07.2009 в 18:45)   письмо автору
 
   для: gOFREe   (19.07.2009 в 18:28)
 

хм..а у вас цикл такой же как и у меня? переменную $menu вы меняете там же?
попробуйте if($name!=='')$header .= '</ul></li>'; заменить на if($name!='')$header .= '</ul></li>';

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 19:07)   письмо автору
 
   для: ride   (19.07.2009 в 18:45)
 

Работает, но очень криво )

<ul id='nav-one' class='nav'>
   <li>категория1
<ul></ul><li>категория2
<ul></ul><li>категория3
<ul><li>подкатегория1</li>

</ul><li>категория4
<ul></ul><li>категория5
<ul><li>подкатегория2</li>
<li>подкатегория3</li>
</li></ul>

  Ответить  
 
 автор: ride   (19.07.2009 в 19:24)   письмо автору
 
   для: gOFREe   (19.07.2009 в 19:07)
 

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

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 19:37)   письмо автору
 
   для: ride   (19.07.2009 в 19:24)
 

Не менял... просто копировал и вставил.

<?
$name 
""
$header.="<ul id='nav-one' class='nav'>";
   while( 
$i_menu = @mysql_fetch_assoc($res) ) {
       
       if(
$name != $i_menu['menu_name']) {
           if(
$name!='')$header .= '</ul></li>';
           
$header .= "<li><a  href='".$i_menu['menu_link']."'>".$i_menu['menu_name']."</a><ul>";
           
$name $i_menu['menu_name'];
           }
           if (
$i_menu['menu_linkR'] != '') {
               
$header .= "<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>";
               }
               }
$header .= "</ul></li></ul>"
?>

  Ответить  
 
 автор: ride   (19.07.2009 в 19:51)   письмо автору
 
   для: gOFREe   (19.07.2009 в 19:37)
 

и запрос..

  Ответить  
 
 автор: ride   (19.07.2009 в 19:59)   письмо автору
 
   для: gOFREe   (19.07.2009 в 19:37)
 

не поверите...
вот результат:

<ul id='nav-one' class='nav'>
    <li><a  href='/'>Главная</a>
        <ul>
            <li><a  href='/test'>TECT</a></li>
        </ul>
    </li>
     <li><a  href='#'>Сайт</a>
        <ul>    
            <li><a  href='/register'>Регистрация</a></li>
            <li><a  href='/about'>О нас</a></li>
        </ul>
    </li>
</ul>


код:

$sql =  "SELECT menu.*, menur.*
                 FROM menu
                 LEFT JOIN menur
                 ON menur.idr = menu.id ORDER by menu.id"; 
$res = mysql_query($sql) or die(mysql_error());  
$name = ""; 
$header="<ul id='nav-one' class='nav'>";
   while( $i_menu = @mysql_fetch_assoc($res) ) {
       
       if($name != $i_menu['menu_name']) {
           if($name!='')$header .= '</ul></li>';
           $header .= "<li><a  href='".$i_menu['menu_link']."'>".$i_menu['menu_name']."</a><ul>";
           $name = $i_menu['menu_name'];
           }
           if ($i_menu['menu_linkR'] != '') {
               $header .= "<li><a  href='".$i_menu['menu_linkR']."'>".$i_menu['menu_nameR']."</a></li>";
               }
               }
echo $header .= "</ul></li></ul>";  


Ищите ошибку

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 21:54)   письмо автору
 
   для: ride   (19.07.2009 в 19:59)
 

Странно... все тоже самое, а выводит криво... или я слепой...
А если еще добавить пару категорий?

  Ответить  
 
 автор: ride   (19.07.2009 в 22:09)   письмо автору
 
   для: gOFREe   (19.07.2009 в 21:54)
 

кстати, дайте дамп

  Ответить  
 
 автор: gOFREe   (19.07.2009 в 22:24)   письмо автору
 
   для: ride   (19.07.2009 в 22:09)
 


--
-- Структура таблицы `tun_menu`
--

CREATE TABLE IF NOT EXISTS `tun_menu` (
  `id` tinyint(4) NOT NULL auto_increment,
  `posid` varchar(255) NOT NULL default '',
  `menu_name` varchar(255) NOT NULL default '',
  `menu_link` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  KEY `id_2` (`id`),
  KEY `id_3` (`id`),
  KEY `posid` (`posid`),
  KEY `menu_name` (`menu_name`),
  KEY `menu_link` (`menu_link`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=9 ;

--
-- Дамп данных таблицы `tun_menu`
--

INSERT INTO `tun_menu` (`id`, `posid`, `menu_name`, `menu_link`) VALUES
(1, '1', 'Главная', '/'),
(8, '7', 'Сайт', '#'),
(3, '3', 'Производители, '/firm'),
(4, '4', 'Тест', '/test1'),
(6, '6', 'Тест2', '/test2');




--
-- Структура таблицы `tun_menuR`
--

CREATE TABLE IF NOT EXISTS `tun_menuR` (
  `id` tinyint(4) NOT NULL auto_increment,
  `idr` tinyint(4) NOT NULL,
  `menu_nameR` varchar(255) NOT NULL default '',
  `menu_linkR` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  KEY `id_2` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=12 ;

--
-- Дамп данных таблицы `tun_menuR`
--

INSERT INTO `tun_menuR` (`id`, `idr`, `menu_nameR`, `menu_linkR`) VALUES
(8, 8, 'подкатегория1', '/cat1'),
(7, 4, 'подкатегория2', '/cat2'),
(11, 8, 'подкатегория3', '/cat3');

  Ответить  
 
 автор: ride   (19.07.2009 в 23:05)   письмо автору
 
   для: gOFREe   (19.07.2009 в 22:24)
 

вроде все как надо:
<ul id='nav-one' class='nav'>
    <li><a  href='/'>Главная</a><ul></ul></li>
    <li><a  href='/firm'>Производители</a><ul></ul></li>
    <li><a  href='/test1'>Тест</a>
        <ul>
            <li><a  href='/cat2'>подкатегория2</a></li>
        </ul>
    </li>
    <li><a  href='/test2'>Тест2</a><ul></ul></li>
    <li><a  href='#'>Сайт</a>
            <ul>
                <li><a  href='/cat1'>подкатегория1</a></li>
                <li><a  href='/cat3'>подкатегория3</a></li>
             </ul>
    </li>
</ul>

  Ответить  
Rambler's Top100
вверх

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