Php mysql parent id

Как проще всего получить всех родителей записи, используя модель id / parent_id в mysql / php?

Я ищу простейший способ рекурсивного получения всех родительских элементов из базы данных с использованием модели наследования смежности/одиночной таблицы ( id, parent_id ). Мой выбор в настоящее время выглядит следующим образом:

$sql = "SELECT e.id, TIME_FORMAT(e.start_time, '%H:%i') AS start_time, $title AS title, $description AS description, $type AS type, $place_name AS place_name, p.parent_id AS place_parent_id, p.city AS place_city, p.country AS place_country FROM event AS e LEFT JOIN place AS p ON p.id = e.place_id LEFT JOIN event_type AS et ON et.id = e.event_type_id WHERE e.day_id = '$day_id' AND e.private_flag = 0 ORDER BY start_time"; 

Каждый event связан с place , и каждый place может быть дочерним по отношению к другому place (примерно до 5 уровней) Возможно ли это в одном select с mysql? В настоящий момент я думаю, что это может быть отдельная функция, которая проходит через возвращаемый массив $events , добавляя элементы place_parent_X , как он есть, но я не уверен, как это реализовать.

3 ответа

CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT NOT DETERMINISTIC READS SQL DATA BEGIN DECLARE _id INT; DECLARE _parent INT; DECLARE _next INT; DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL; SET _parent = @id; SET _id = -1; IF @id IS NULL THEN RETURN NULL; END IF; LOOP SELECT MIN(id) INTO @id FROM place WHERE parent = _parent AND id > _id; IF @id IS NOT NULL OR _parent = @start_with THEN SET @level = @level + 1; RETURN @id; END IF; SET @level := @level - 1; SELECT id, parent INTO _id, _parent FROM place WHERE END LOOP; END SELECT id, parent FROM ( SELECT hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level FROM ( SELECT @start_with := 0, @id := @start_with, @level := 0 ) vars, t_hierarchy WHERE @id IS NOT NULL ) ho JOIN place hi ON hi.id = ho.id 

В последнем запросе будут выбраны все потомки заданного node (который вы должны установить в переменной @start_with )

Читайте также:  Python get all installed packages

Чтобы найти всех предков данного node, вы можете использовать простой запрос без функций:

SELECT @r AS _id, @r := ( SELECT parent FROM place WHERE ) AS parent FROM ( SELECT @r := @node_id ) vars, place 

Эта статья в моем блоге описала этот запрос более подробно:

Чтобы оба этих решения работали в разумные сроки, вам нужно иметь индексы как для id , так и parent .

Убедитесь, что ваш id определяется как PRIMARY KEY , и у вас есть второй индекс на parent .

Источник

MySQL SELECT Tree Parent IDs

Как я могу сортировать записи инструкции SELECT, чтобы они представляли действительное дерево?

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

ID Parent ID Title -------------------------------------------- 0 NULL Root 1 0 Node A 2 0 Node B 3 1 Sub-Node C 4 1 Sub-Node D 5 3 Sub-Node E 
ID Parent ID Title -------------------------------------------- 0 NULL Root 1 0 Node A 3 1 Sub-Node C 5 3 Sub-Node E 4 1 Sub-Node D 2 0 Node B 

Визуализация данных

Root Node A Sub-Node C Sub-Node E Sub-Node D Node B 

Solutions Collecting From Web of «MySQL SELECT Tree Parent IDs»

Вы можете использовать вложенные наборы. Ознакомьтесь с этой статьей:

Управление иерархическими данными в MySQL

Автор описывает несколько разных методов построения иерархии в SQL, в комплекте с примерами запросов. Это очень хорошо читать об этом предмете!

Следуя совету @Blindy, я реализовал этот вид с PHP. Вот две функции, которые, похоже, довольно легко решают эту проблему.

protected function _sort_helper(&$input, &$output, $parent_id) < foreach ($input as $key =>$item) if ($item->parent_id == $parent_id) < $output[] = $item; unset($input[$key]); // Sort nested!! $this->_sort_helper(&$input, &$output, $item->id); > > protected function sort_items_into_tree($items) < $tree = array(); $this->_sort_helper(&$items, &$tree, null); return $tree; > с protected function _sort_helper(&$input, &$output, $parent_id) < foreach ($input as $key =>$item) if ($item->parent_id == $parent_id) < $output[] = $item; unset($input[$key]); // Sort nested!! $this->_sort_helper(&$input, &$output, $item->id); > > protected function sort_items_into_tree($items) < $tree = array(); $this->_sort_helper(&$items, &$tree, null); return $tree; > 

Мне было бы интересно услышать, есть ли более простой подход, но, похоже, это работает.

MySQL не поддерживает рекурсивные запросы

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

См. Эти сообщения для некоторых идей и примеров:

Иерархия категорий (PHP / MySQL)

как мы можем написать mysql-запрос, где у родительского идентификатора есть дочерний идентификатор, а в следующий раз дочерний id – родительский идентификатор, как я могу это сделать?

Я только что закончил эту рекурсивную функцию и подумал, что это изящный способ решить эту проблему. Вот что я сделал, как только я сделал базовый запрос SELECT mysql:

function orderChildren($data)< $tree = array(); foreach($data as $value)< if($value['parent_id'] == null)< // Values without parents $tree[$value['id']] = $this->goodParenting($value, $data); > > return $tree; > private function goodParenting($parent, $childPool)< foreach($childPool as $child)< if($parent['id'] == $child['parent_id'])< $parent['children'][$child['id']] = $this->goodParenting($child, $childPool); > > return $parent; > 

Вот еще один способ сделать вашу функцию PHP.

function buildTree() < $data = array(); $pointers = array(); $sql = "SELECT ID,PARENT,TITLE FROM TREE ORDER BY TITLE ASC"; $res = $this->db->query($sql); while ($row = $res->fetch(PDO::FETCH_ASSOC)) < if(!isset($pointers[$row['ID']])) < $pointers[$row['ID']] = $row; >if(!empty($row['PARENT'])) < if(!isset($pointers[$row['PARENT']])) < $pointers[$row['PARENT']] = $row; >$pointers[$row['PARENT']][$row['ID']] = &$pointers[$row['ID']]; > else < $data[$row['ID']] = &$pointers[$row['ID']]; // This is our top level >> unset($pointers); return $data; > этот function buildTree() < $data = array(); $pointers = array(); $sql = "SELECT ID,PARENT,TITLE FROM TREE ORDER BY TITLE ASC"; $res = $this->db->query($sql); while ($row = $res->fetch(PDO::FETCH_ASSOC)) < if(!isset($pointers[$row['ID']])) < $pointers[$row['ID']] = $row; >if(!empty($row['PARENT'])) < if(!isset($pointers[$row['PARENT']])) < $pointers[$row['PARENT']] = $row; >$pointers[$row['PARENT']][$row['ID']] = &$pointers[$row['ID']]; > else < $data[$row['ID']] = &$pointers[$row['ID']]; // This is our top level >> unset($pointers); return $data; > не function buildTree() < $data = array(); $pointers = array(); $sql = "SELECT ID,PARENT,TITLE FROM TREE ORDER BY TITLE ASC"; $res = $this->db->query($sql); while ($row = $res->fetch(PDO::FETCH_ASSOC)) < if(!isset($pointers[$row['ID']])) < $pointers[$row['ID']] = $row; >if(!empty($row['PARENT'])) < if(!isset($pointers[$row['PARENT']])) < $pointers[$row['PARENT']] = $row; >$pointers[$row['PARENT']][$row['ID']] = &$pointers[$row['ID']]; > else < $data[$row['ID']] = &$pointers[$row['ID']]; // This is our top level >> unset($pointers); return $data; > 
  • Ошибка модуля входа: свойство «LoginForm._id» не определено
  • Разрешения файла и CHMOD: Как установить 777 в PHP при создании файла?
  • Как сделать NAT с сокетами PHP
  • как вызвать ajax на интерфейсе wordpress
  • установить кодировку при сохранении файлов с помощью php
  • Использование нескольких модулей в одном представлении
  • Как я могу использовать буферизацию var_dump + output без ошибок памяти?
  • Как установить расширение mbstring
  • Нужна помощь в вычислении MySQL-запроса для подсчета, если определенное число
  • Как изменить формат по умолчанию на created_at и update_at значение laravel
  • PHP Strtotime -1month -2month
  • Обновление JQuery Progressbar с ответом JSON в запросе ajax
  • как вставлять видео в код laravel
  • Yii: Как управлять видео при использовании расширения multuploadfiles
  • не удалось открыть поток: не найдено подходящей обертки

Источник

Оцените статью