Выборка из MySQL с рекурсией, решение на PHP
Как известно рекурсивные запросы MySQL не поддерживает, что порождает множество сложностей при необходимости получить данные, например в древовидной структуре. Но есть ряд изящных решений на PHP, которые можно использовать, для построения древовидных массивов из полученных данных от БД.
Сразу оговорюсь. Распространенный метод, которым пользуются многие новички, не самый лучший и даже более того, он может положить весь веб-сервер на лопатки, или выбить из процессов MySQL. Как минимум это чревато сильными притормаживании при работе такого метода. Что это я, все вокруг да около, собственно вот он сам метод:
(в примере используется класс для работы с БД и его методы: getAll — выборка списка строк из БД)
$sql="SELECT * FROM table WHERE parent_id = 0 ORDER BY id ASC"; // получаем список элементов лежащих в корне $items = $DB->getAll($sql); // получаем список записей из БД $new_array = array(); // Новый массив, содержащий дерево foreach($items as $item) { $sql="SELECT * FROM table WHERE parent_id = '{$item['id']}' ORDER BY id ASC"; // получаем список элементов потомков $items_2 = $DB->getAll($sql); // получаем список записей из БД $item['child'] = $items_2; $new_array[]=$item; } |
Многочисленные запросы в БД для выборки потомков и построения дерева. Вариант, но крайне нагружающий MySQl. Так, что я предостерегаю вас от его использования.
По этому, следует использовать немного модифицированный алгоритм, где выборка будет происходить единожды, и выбираться будет сразу вся таблица из БД, а уже далее средствами PHP производиться раскладка выборки в многомерный древовидный массив. Пример:
$sql="SELECT * FROM table ORDER BY id ASC"; // получаем список элементов лежащих в корне $rs= $DB->getAll($sql); // получаем список записей из БД $rs2 = array(); foreach ($rs as $row) { $rs2[$row['parent_id']][] = $row; } function RecursiveTree2(&$rs,$parent) { $out = array(); if (!isset($rs[$parent])) { return $out; } foreach ($rs[$parent] as $row) { $chidls = RecursiveTree2($rs, $row['id']); if ($chidls) $row['childs'] = $chidls; $out[] = $row; } return $out; } print_r(RecursiveTree2($rs2 ,0)); |
Несколько массивов, которые используются как временные, но зато всего один запрос к базе данных. Автор данного решение, для наглядности сгруппировал выборку в двумерный массив, при этом осуществил группировку по родителю.
Следующий пример, вообще решает задачу в рамках одного цикла. При этом используется вспомогательный массив, которых хранит значение, а именно «путь» к родительскому элементу ветки, с целью дописать к нему новую ветку(потомка).
Пример: $x[1][‘childs’][1][‘childs’][0], таким образом мы знаем куда дописать потомка и тем самым построить дерево.
$sql="SELECT * FROM table ORDER BY id ASC"; // получаем список элементов лежащих в корне $rs= $DB->getAll($sql); // получаем список записей из БД $tree = array(0=>array('id'=>0, 'parent_id'=>0, 'value'=>'root')); $temp = array(0=>&$tree[0]); foreach ($rs as $val) { $parent = &$temp[ $val['parent_id'] ]; if (!isset($parent['childs'])) { $parent['childs'] = array(); } $parent['childs'][$val['id']] = $val; $temp[$val['id']] = &$parent['childs'][$val['id']]; } unset($rs, $temp, $val, $parent); print_r($tree[0]['childs']); |
На закуску еще один пример вывода дерева, например такой пример может применяться при выводе категорий с вложенным неограниченным числом подкатегорий
SELECT ID, ParentID, Title FROM Tree; <?php while($row = mysql_fetch_assoc($res)) { $tree[$row[ParentID]][$row[ID]] = $row[Title];} function ShowTree($tree, $pid=0) { echo ; foreach( $tree as $id => $root) { if($pid!=$id)continue; if(count($root)) { foreach($root as $key => $title) { echo {$title}; if(count($tree[$key]))ShowTree($tree,$key); } } } echo ; } |
Надеюсь данный пост будет вам полезен. Пост написан в рамках заметки, для самого себя и конечно читателей моего блога. Примеры позаимствованы из блога Абрамова Тимура.
Похожие записи
Оставить комментарий
Senior, Architector
предложить оффер
- Nginx редирект на другой сервис с сохранением URL спросил (а) Сергей
- Исполнитель пропал, почему такое случается и понять с кем работать? спросил (а) Артем
- Можно ли WordPress считать универсальным движком? спросил (а) Андрей
- Что такое самописный скрипт или CMS? спросил (а) Антон
- Как при поиске в linux используя grep, добавить исключения? спросил (а) Алексей
- Интеграция Тинькофф банк Эквайринг на сайт для приема платежей к записи
- Скрипт парсинга форума к записи
- Интеграция по API с страховым маркетплейсом INSSMART к записи
- Интеграция Тинькофф банк Эквайринг на сайт для приема платежей к записи
- Joomla не пускает в админку к записи
- Все что нужно для работы с WSDL к записи
- Интеграция по API с страховым маркетплейсом INSSMART к записи
Archive
- +2023 (3)
- Апрель 2023 (1)
- Март 2023 (1)
- Февраль 2023 (1)
- +2022 (21)
- Декабрь 2022 (11)
- Ноябрь 2022 (1)
- Май 2022 (2)
- Апрель 2022 (2)
- Март 2022 (3)
- Февраль 2022 (1)
- Январь 2022 (1)
- +2021 (17)
- Декабрь 2021 (5)
- Ноябрь 2021 (2)
- Июль 2021 (1)
- Июнь 2021 (2)
- Май 2021 (5)
- Апрель 2021 (1)
- Март 2021 (1)
- +2020 (20)
- Декабрь 2020 (6)
- Сентябрь 2020 (2)
- Август 2020 (1)
- Июль 2020 (2)
- Май 2020 (2)
- Апрель 2020 (2)
- Март 2020 (2)
- Февраль 2020 (1)
- Январь 2020 (2)
- +2019 (18)
- Декабрь 2019 (3)
- Ноябрь 2019 (2)
- Октябрь 2019 (2)
- Сентябрь 2019 (1)
- Август 2019 (2)
- Июль 2019 (1)
- Июнь 2019 (1)
- Апрель 2019 (2)
- Март 2019 (1)
- Февраль 2019 (3)
- +2018 (44)
- Декабрь 2018 (4)
- Ноябрь 2018 (7)
- Октябрь 2018 (8)
- Сентябрь 2018 (1)
- Август 2018 (4)
- Июль 2018 (5)
- Май 2018 (3)
- Апрель 2018 (7)
- Март 2018 (1)
- Февраль 2018 (2)
- Январь 2018 (2)
- +2017 (19)
- Декабрь 2017 (2)
- Ноябрь 2017 (1)
- Октябрь 2017 (1)
- Сентябрь 2017 (2)
- Июль 2017 (1)
- Июнь 2017 (1)
- Май 2017 (2)
- Апрель 2017 (3)
- Март 2017 (2)
- Февраль 2017 (1)
- Январь 2017 (3)
- +2016 (37)
- Декабрь 2016 (3)
- Ноябрь 2016 (3)
- Октябрь 2016 (2)
- Сентябрь 2016 (3)
- Август 2016 (7)
- Июнь 2016 (3)
- Май 2016 (3)
- Апрель 2016 (3)
- Март 2016 (1)
- Февраль 2016 (1)
- Январь 2016 (8)
- +2015 (36)
- Ноябрь 2015 (5)
- Октябрь 2015 (4)
- Сентябрь 2015 (1)
- Август 2015 (8)
- Июнь 2015 (1)
- Май 2015 (4)
- Апрель 2015 (8)
- Март 2015 (3)
- Февраль 2015 (2)
- +2014 (26)
- Ноябрь 2014 (2)
- Октябрь 2014 (5)
- Сентябрь 2014 (6)
- Июль 2014 (1)
- Июнь 2014 (2)
- Май 2014 (3)
- Апрель 2014 (6)
- Февраль 2014 (1)
- +2013 (27)
- Декабрь 2013 (2)
- Ноябрь 2013 (1)
- Октябрь 2013 (1)
- Август 2013 (1)
- Июль 2013 (3)
- Июнь 2013 (10)
- Май 2013 (1)
- Апрель 2013 (2)
- Февраль 2013 (3)
- Январь 2013 (3)
- +2012 (42)
- Декабрь 2012 (2)
- Ноябрь 2012 (3)
- Октябрь 2012 (7)
- Сентябрь 2012 (2)
- Август 2012 (1)
- Июль 2012 (3)
- Июнь 2012 (2)
- Май 2012 (6)
- Апрель 2012 (2)
- Март 2012 (8)
- Февраль 2012 (5)
- Январь 2012 (1)
- +2011 (57)
- Декабрь 2011 (6)
- Ноябрь 2011 (2)
- Октябрь 2011 (3)
- Сентябрь 2011 (5)
- Август 2011 (4)
- Июль 2011 (3)
- Июнь 2011 (3)
- Май 2011 (3)
- Апрель 2011 (4)
- Март 2011 (10)
- Февраль 2011 (5)
- Январь 2011 (9)
- +2010 (43)
- Декабрь 2010 (7)
- Ноябрь 2010 (21)
- Октябрь 2010 (14)
- Сентябрь 2010 (1)
Свежие записи
- Поиск проблем на сервере (загрузка CPU 100%). Разбор. 15.04.2023
- Почему на сайте, что-то может «само» сломаться? 16.03.2023
- Как быстро писать статьи под низкочастотные запросы 28.02.2023
- Разработка сайта для Андрея Ковалёва 30.12.2022
- Разработка плагина для WordPress — Аудиогид 12.12.2022