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

Форум MySQL

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

 

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

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

тема: Многотабличный запрос. Можно ли разложить?
 
 автор: Лена   (12.10.2009 в 10:55)   письмо автору
 
 

Запрос:

SELECT a.area_id ai,a.area_name an,
b.block_id bi,b.block_name bn,
mn.menu_id mmi,mn.menu_name mmn,
md.mod_id mdi,md.mod_name mdn,
mi.menu_items_id mii,mi.menu_items_name min
FROM area a
LEFT JOIN blocks b ON a.area_id = b.area_id
LEFT JOIN menu mn ON b.block_id = mn.block_id
LEFT JOIN modules md ON b.block_id = md.block_id
LEFT JOIN menu_items mi ON mn.menu_id = mi.menu_id
ORDER BY a.pos


На выходе должно быть такое:
Область1
Блок 1
Блок 2
Модуль 1
Модуль2
Меню 1
Блок 3
Возможно ли это разложить, если делать одним запросом? Или лучше этот запрос разбить на маленькие?

  Ответить  
 
 автор: cheops   (12.10.2009 в 11:47)   письмо автору
 
   для: Лена   (12.10.2009 в 10:55)
 

>Возможно ли это разложить, если делать одним запросом?
Под "разложением" что имеется в виду?

  Ответить  
 
 автор: Лена   (12.10.2009 в 11:56)   письмо автору
 
   для: cheops   (12.10.2009 в 11:47)
 

>Под "разложением" что имеется в виду?
Список, который я указала в первом посте.
Вывести область, список блоков к этой области, к блоку, если есть, список модулей и меню, которые входят в этот блок, к меню - список ссылок этого меню.
Проблема в том, что при этом область выводится несколько раз, если в ней много блоков, блоки тоже выводятся много раз, если в них есть модули и т.д. Вроде как теперь понятно объяснила...

  Ответить  
 
 автор: Valick   (12.10.2009 в 12:07)   письмо автору
1 Кб
 
   для: Лена   (12.10.2009 в 11:56)
 

теперь понятно
я делал как-то так
может разберётесь))

  Ответить  
 
 автор: Лена   (12.10.2009 в 12:35)   письмо автору
 
   для: Valick   (12.10.2009 в 12:07)
 

Я точно так же делаю, если уровней два: допустим, области и в них - блоки. А если уровней больше, тогда ничего не получается.

  Ответить  
 
 автор: Trianon   (12.10.2009 в 13:52)   письмо автору
 
   для: Лена   (12.10.2009 в 12:35)
 

ORDER BY неполон

  Ответить  
 
 автор: Лена   (12.10.2009 в 16:01)   письмо автору
 
   для: Trianon   (12.10.2009 в 13:52)
 

ORDER BY можно было бы добавить, если бы имела смысл сама идея.
А так пришлось разбивать на мелкие запросы и делать много циклов.

  Ответить  
 
 автор: Valick   (12.10.2009 в 16:29)   письмо автору
 
   для: Лена   (12.10.2009 в 16:01)
 

где логика?

  Ответить  
 
 автор: Лена   (12.10.2009 в 17:47)   письмо автору
 
   для: Valick   (12.10.2009 в 16:29)
 

>где логика?
Объясняю где.
В том примере, что прикрепили вы, раскладывается только, допустим, какие-то категории и подкатегории к каждой из этих категорий(2 уровня). У меня же идет категории-подкатегории-подкатегории этих подкатегорий и т.д. Уровней вложенности уже 3 и более. И раскладывать так, как вы это делали, не получится.
Поэтому сделала много маленьких запросов и теперь раскладываю области, внутри этих областей - цикл для блоков, внутри блоков - цикл для меню, внутри меню - цикл для пунктов меню.

  Ответить  
 
 автор: Valick   (12.10.2009 в 18:07)   письмо автору
 
   для: Лена   (12.10.2009 в 17:47)
 

И раскладывать так, как вы это делали, не получится.
Скажу честно, не пробовал, но разницы не вижу
Мой случай:
отношение второго к первому (грубо говоря)
Ваш случай:
1)отношение третьего ко второму (= второе к первому)
2)отношение второго к первому (= второе к первому)
количество полей результирующей таблицы будет зависеть от глубины вложенности
важно только определиться какие поля сравнивать
просто измениться глубина вложенности в отличии от моего варианта, а если буферную переменную организовать как стек, то глубина вложенности вообще не будет иметь значения (в разумных пределах)
но это всего лишь теория, может и не стоит оно того

  Ответить  
 
 автор: Trianon   (12.10.2009 в 20:28)   письмо автору
 
   для: Лена   (12.10.2009 в 16:01)
 

Идея имеет смысл, но лишь при полном ORDER BY
<?
$sql 
"
SELECT t1.f1, t2.f2, t3.f3, t4.f4 
  FROM t1 
    LEFT JOIN t2 ON t2.t1_id = t1.id 
    LEFT JOIN t3 ON t3.t2_id = t2.id 
    LEFT JOIN t4 ON t4.t3_id = t3.id 
  ORDER BY t1.pos, t1.id, 
            t2.pos, t2.id, 
             t3.pos, t3.id, 
              t4.pos, t4.id
"
;

for(
$res mysql_query($sql), $c1 null $row mysql_fetch_row($res); )
{
    list(
$f1$f2$f3$f4) = $row;
    if(
$c1 !== $f1)
    {
      
$c1 $f1$c2 null
      echo 
$c1
    }
    if(
$c2 !== $f2)
    {
      
$c2 $f2$c3 null;
      echo 
$c2
    }
    if(
$c3 !== $f3)
    {
      
$c3 $f3;  
      echo 
$c3
    }
    if(
$f4 !== null
        echo 
$f4
}

  Ответить  
 
 автор: Trianon   (13.10.2009 в 15:31)   письмо автору
 
   для: Trianon   (12.10.2009 в 20:28)
 

"Несколько" исправил ответ.
Пардон, в первом варианте была лажа откровенная :)

  Ответить  
 
 автор: Лена   (14.10.2009 в 10:20)   письмо автору
 
   для: Trianon   (13.10.2009 в 15:31)
 

Применила к своему случаю.

<?php
$sql 
"SELECT a.area_id ai,a.area_name an,
b.block_id bi,b.block_name bn,
mn.menu_id mmi,mn.menu_name mmn,
md.mod_id mdi,md.mod_name mdn,
mi.menu_items_id mii,mi.menu_items_name min
FROM area a
LEFT JOIN blocks b ON a.area_id = b.area_id
LEFT JOIN menu mn ON b.block_id = mn.block_id
LEFT JOIN modules md ON b.block_id = md.block_id
LEFT JOIN menu_items mi ON mn.menu_id = mi.menu_id
ORDER BY a.pos,ai,
             b.pos,bi,
                 mn.poss,mmi,
                     md.pos,mdi,
                         mi.pos,mii
"
;
//массив для шаблона
$arr = array();
for(
$res mysql_query($sql), $c1 null $row mysql_fetch_row($res); ){
    list(
$ai$an$bi$bn,$mmi$mmn,$mdi$mdn,$mii$min) = $row;
     
$an htmlspecialchars($an);
     
$bn htmlspecialchars($bn);
     
$mmn htmlspecialchars($mmn);
     
$mdn htmlspecialchars($mdn);
     
$min htmlspecialchars($min);
    if(
$c1 !== $ai){
      
$c2 null;
      
//echo $c1; echo $an . '<br>';
      
$arr[$c1 $ai] = array('area' => $an'sub'=>array());
   }

    if(
$c2 !== $bi){
      
$c3 null;
      
//echo $c2; echo $bn . '<br>';
      
$arr[$c1 $ai]['sub'][$c2 $bi] = array('block' => $bn'sub'=>array());
    }

    if(
$c3 !== $mmi && $c4 !== $mdi){
      
//echo $c3; echo $mmn . '<br>'; echo $mdn . '<br>';
    
$arr[$c1 $ai]['sub'][$c2 $bi]['sub'][$c3 $mmi] = array('menu'=>$mmn,'sub'=>array());
    
$arr[$c1 $ai]['sub'][$c2 $bi]['sub'][$c4 $mdi] = array('mod'=>$mdn,'sub'=>array());
    }

    if(
$mii !== null){
    
//echo $mii; //echo $min . '<br>';
    
$arr[$c1 $ai]['sub'][$c2 $bi]['sub'][$c3 $mmi]['sub'][$mii] = $min;
    }
}
$smarty->assign('arr',$arr);
$smarty->display('perm.tpl');
?>


Шаблон не нравится. Много циклов.

<?php
{foreach from=$arr item=area key=area_k}
    {foreach 
from=$area item=as key=as_k}
        {if 
$as_k == 'area'}
            <
div><a href "">{$as}</a></div>
        {/if}
        {if 
$as_k == 'sub'}
            {foreach 
from=$as item=block key=block_k}
                    {foreach 
from=$block item=bs key=bs_k}
                        {if 
$bs_k == 'block'}
                            <
div style 'text-indent="1.6em"'><a href "">{$bs}</a></div>
                        {/if}
                        {if 
$bs_k == 'sub'}
                            {foreach 
from=$bs item=menu key=menu_k}
                                {foreach 
from=$menu item=ms key=ms_k}
                                     {if 
$ms_k == 'menu' || $ms_k == 'mod'}
                                        <
div style 'text-indent="3.2em"'><a href "">{$ms}</div>
                                    {/if}
                                    {if 
$ms_k == 'sub'}
                                         {foreach 
from=$ms item=item key=item_k}
                                            <
div style 'text-indent="6.4em"'><a href "">{$item}</a></div>
                                         {/foreach}
                                    {/if}
                                 {/foreach}
                            {/foreach}
                        {/if}
                    {/foreach}
            {/foreach}
        {/if}
    {/foreach}
{/foreach}


  Ответить  
 
 автор: cheops   (12.10.2009 в 12:15)   письмо автору
 
   для: Лена   (12.10.2009 в 11:56)
 

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

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

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