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

Форум MySQL

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

 

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

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

тема: рекурсивная выборка
 
 автор: Slo_Nik   (23.12.2011 в 03:32)   письмо автору
 
 

Доброй ночи.
Есть задача рекурсивно выбрать из таблицы данные (статьи)
структура базы

<?php 
CREATE TABLE 
IF NOT EXISTS `articles`(
 `
id_articleINT(3NOT NULL AUTO_INCREMENT/* id статьи */
 
`title_artVARCHAR(100NOT NULL/* заголовок статьи */
`id_chapterINT(3NOT NULL/* id главы, к которой принадлежит статья */
 
`id_sub_chapterINT(3NOT NULL DEFAULT 0/* id родительской статьи */
 
PRIMARY KEY(`id_article`),
)
ENGINE=MyISAM DEFAULT CHARSET=utf8;

в итоге должно получится подобие "дерева"

1
1.1
1.2
1.2.1
1.2.2
1.2.3
1.2.3.1
1.2.3.2

и так далее

уровень вложенности неограничен
посмотрел в инете, понял, что MySql не поддерживает рекурсивные запрос, есть куча статей, как это обойти, но даты публикаций смущают, начиная от 2004 и заканчивая 2009 годами, явно устарели.
Есть вариант написания рекурсивной функции, такая мысль и мне приходила в голову, но автора статьи заплевали (((
Посоветуйте, как можно решить проблему?

  Ответить  
 
 автор: cheops   (23.12.2011 в 11:21)   письмо автору
 
   для: Slo_Nik   (23.12.2011 в 03:32)
 

Ммм... в SQL не очень сильно меняется все, год статьи еще не показатель. Рекурсивный подход - это не плохой подход, однако, рекурсию лучше организовывать таким образом, чтобы она не требовала множества обращений к базе данных. Т.е. не обязательно выполнять сотни запросов - для учебной задачи это нормально, в реальности же обычно выгружают все данные в массив и рекурсию ведут по массиву в оперативной памяти.

  Ответить  
 
 автор: kosta_in_net   (23.12.2011 в 13:05)   письмо автору
 
   для: cheops   (23.12.2011 в 11:21)
 

Тут смежная тема была http://www.softtime.ru/forum/read.php?id_forum=3&id_theme=76480
Может что-то подскажет...

  Ответить  
 
 автор: Slo_Nik   (23.12.2011 в 13:30)   письмо автору
 
   для: kosta_in_net   (23.12.2011 в 13:05)
 

по ссылке, что дали Вы и по ссылке, что указывая я в первом посте практически одинаковые решения, рекурсивный запрос к базе данных, что, как я понимаю, не очень хорошо.

p.s. погорячился, в Вашем примере нет рекурсивного обращения к базе )))

  Ответить  
 
 автор: Slo_Nik   (23.12.2011 в 13:25)   письмо автору
 
   для: cheops   (23.12.2011 в 11:21)
 

Вы имеете ввиду работу с массивом, который возвращает mysql_fetch_assoc()?
То есть, выгрузить все статьи для определённой главы и уже через foreach() разбирать по уровням?

  Ответить  
 
 автор: cheops   (23.12.2011 в 13:34)   письмо автору
 
   для: Slo_Nik   (23.12.2011 в 13:25)
 

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

  Ответить  
 
 автор: Slo_Nik   (23.12.2011 в 13:37)   письмо автору
 
   для: cheops   (23.12.2011 в 13:34)
 

Спасибо, буду пробовать. подсказку уже дали )))

  Ответить  
 
 автор: deimand   (23.12.2011 в 23:27)   письмо автору
 
   для: Slo_Nik   (23.12.2011 в 03:32)
 

http://softtime.ru/forum/read.php?id_forum=1&id_theme=81855#post487656

  Ответить  
 
 автор: Slo_Nik   (24.12.2011 в 23:58)   письмо автору
 
   для: deimand   (23.12.2011 в 23:27)
 

Благодарю за очередную подсказку, но уже решил главную задачу... подошёл вариант по предыдущей ссылке от kosta_in_net

  Ответить  
 
 автор: Slo_Nik   (25.12.2011 в 00:02)   письмо автору
 
   для: Slo_Nik   (23.12.2011 в 03:32)
 

С главной задачей справился, но возник такой вопрос, как автоматически пронумеровать список статей в таком порядке?


1.1 
1.2 
1.2.1 
1.2.2 
1.2.3 
1.2.3.1 
1.2.3.2 
и так далее 

Со статьями первого уровня я справился, но вот последующие уровни не пойму как пронумеровать.

  Ответить  
 
 автор: SerG7   (25.12.2011 в 12:43)   письмо автору
 
   для: Slo_Nik   (25.12.2011 в 00:02)
 

непонятна структура
`id_chapter` INT(3) NOT NULL, /* id главы, к которой принадлежит статья */
`id_article` INT(3) NOT NULL AUTO_INCREMENT, /* id статьи */
`id_sub_chapter` INT(3) NOT NULL DEFAULT 0, /* id родительской статьи */ 


правильная структура
Полка
|__Книга
    |__Лист
или
Полка
|__Книга
    |__Глава
        |__Лист
и т.д

Раздел
|__Категория
    |__Статья

Рекурсия не есть хорошо..это множественное обращение к серверу SQL
Правильно было сказано..один запрос ..результат в массив ..а потом разбирать его в цикле..
А вот в цикле и получится это дерево пронумеровать так как вы хотите...

  Ответить  
 
 автор: Slo_Nik   (25.12.2011 в 14:01)   письмо автору
 
   для: SerG7   (25.12.2011 в 12:43)
 

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

1 /* порядковый номер главы */
1.1 /* порядковый номер главы + порядковый номер статьи (родитель)*/
1.1.1 /* порядковый номер главы + порядковый номер статьи(родитель) + порядковый номер статьи(потомок) */

не получается пока сохранить порядковый номер статьи(родитель) когда вывожу "потомка" этой статьи....

  Ответить  
 
 автор: kosta_in_net   (09.01.2012 в 18:19)   письмо автору
 
   для: Slo_Nik   (25.12.2011 в 14:01)
 

думаю, без дампа данных тут не понять

  Ответить  
 
 автор: Slo_Nik   (09.01.2012 в 23:09)   письмо автору
9.8 Кб
 
   для: kosta_in_net   (09.01.2012 в 18:19)
 

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

<?php 
$query 
"SELECT `ch`.`name_chapter`,
                 `ch`.`id_chapter`,
                 `ch`.`order_chapter`,
                 `art`.`id_article`,
                 `art`.`order_article`,
                 `art`.`title_art`,
                 `art`.`id_sub_chapter`,
                 `art`.`block`
            FROM `chapter` AS `ch`
       LEFT JOIN `articles` AS `art` ON(`art`.`id_chapter` = `ch`.`id_chapter`)
           WHERE `ch`.`id_chapter` = "
.$id_chapter."
        ORDER BY `art`.`id_article`"
;
 
$view mysql_query($query);
 if(!
$view) echo "Ошибка № 2<br>".mysql_errno();
  
$root = array() /* массив статей-родителей */;
  
$child = array()/* массив статей-потомков */;
 while(
$view_art mysql_fetch_object($view)){
  
$title_ch $view_art->name_chapter/* название главы */
  
$order $view_art->order_chapter/* порядковый номер главы */
/* заполнение массивов статьями */
  
if($view_art->id_sub_chapter == 0){
   
$root[] = $view_art;
  }
  else{
   
$child[$view_art->id_sub_chapter][] = $view_art;
  }
 }
/* рекурсивная функция вывода статей в виде "дерева" */
  
function listTree($r$c){ 
    
$html "";
    foreach(
$r as $v){
      
$title = ($v->block == 'show')
               ? 
"<a href='?action=view&amp;view=view_article&amp;id_article=".$v->id_article."'>".$v->title_art."</a>"
               
"<a class='block' href='?action=view&amp;view=view_article&amp;id_article=".$v->id_article."'>".$v->title_art."</a>";
      
$chapter $v->order_chapter;
      
$root_art $v->order_article;
      
/* $chapte и $root_art порядковые номер главы и статей */
      
$html .= "<ul class='ul-article-list'><li>".$chapter.".".$root_art.".".$title;
      if(isset(
$c[$v->id_article])){
       
$html .= listTree($c[$v->id_article], $c);
      }
      
$html .= "</li></ul>";
    }
    return 
$html;
  }

echo 
listTree($root$child);

  Ответить  
 
 автор: nmahkamov   (04.02.2012 в 12:01)   письмо автору
 
   для: Slo_Nik   (09.01.2012 в 23:09)
 

Привет!
Перейдите http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=84793 и читайте мой пост. Там все реализовано.

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

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