[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как сделать рекурсивный запрос?
Страницы: 1, 2, 3
Эли4ка
Цитата (Kusss @ 26.03.2019 - 22:46)
А от чего пляшем то. Нужно получить всех предшественников или потомков ?

Предшественников. Про потомков я даже как-то и не думала blink.gif
VeRTak
Эли4ка

Если версию mysql 5.7 там есть рекурсия, если 5.6 можно функцией примерно так


BEGIN
DECLARE i INT DEFAULT 1000000;
IF (id>0) THEN
wet : WHILE i>0 DO
IF(@to_id = 0)
THEN
SET @to_id = NULL;
RETURN @id;
LEAVE wet;
ELSE
SELECT
id, to_id
FROM table
WHERE
id = id
INTO @id,@to_id;
SET id = @to_id;
END IF;
SET i=i-1;
END WHILE wet;
END IF;
END


p.s накидал по быстрому, но думаю суть понятна. Можно конечно и с другой стороны зайти и по другому написать процедуру, это чисто показать что это такое
VeRTak
Цитата (Zzepish @ 26.03.2019 - 23:26)
Обычно такое не педалят на огромных таблицах (ибо тупо стремно).


Смотря как педалить smile.gif Можно такой велосипед собрать, что и педали будут быстро крутиться, а вот прикладывать на php рекурсивные вещи которые завязаны на бд, я бы не советовал никогда
VeRTak
Выше чет не то накидал, вернет последнего потомка, вот такая должна подойти процедура


BEGIN
DECLARE i INT DEFAULT 1000000;
IF (id>0) THEN
wet : WHILE i>0 DO
IF(@to_id = 0)
THEN
SELECT
id,to_id
FROM test
WHERE to_id NOT IN (@id)
LEAVE wet;
ELSE
SELECT
@id := id, @to_id := to_id
FROM table
WHERE
id = id;
END IF;
SET id = @to_id;
SET i=i-1;
END WHILE wet;
ELSE
SELECT
'Задайте правильный id';
END IF;
END
kaww
Цитата (Эли4ка @ 27.03.2019 - 00:46)
То есть в поле to_id содержиться указатель на id. Эдакая рекурсия.

Эдакое дерево. А для работы с деревьями в реляционных БД придумано много способов: Adjacency List, Nested Sets, Materialized Path, Closure Table и, наверняка, есть что-то еще.
Например, возьмем Closure Table, по причине, что основные операции с деревьями в нем делаются достаточно просто. К тому же данные самого дерева хранятся в отдельной таблице, а это значит, что его поддержку можно реализовать на триггерах, и таким образом не придется думать об этом на стороне php и в случае ТС не придется менять уже существующую таблицу. Тогда чтобы вывести всех потомков, достаточно выполнить запрос вида
SELECT p.*
FROM products AS p
INNER JOIN products_tree AS t ON p.id=t.ancestor_id
WHERE t.descendant_id='$id'
Эли4ка
Если кому нужно таблица-вот
Эли4ка
Цитата (kaww @ 27.03.2019 - 03:33)
Эдакое дерево. А для работы с деревьями в реляционных БД придумано много способов: Adjacency List, Nested Sets, Materialized Path, Closure Table и, наверняка, есть что-то еще.
Например, возьмем Closure Table, по причине, что основные операции с деревьями в нем делаются достаточно просто. К тому же данные самого дерева хранятся в отдельной таблице, а это значит, что его поддержку можно реализовать на триггерах, и таким образом не придется думать об этом на стороне php и в случае ТС не придется менять уже существующую таблицу. Тогда чтобы вывести всех потомков, достаточно выполнить запрос вида

Это все да. Но запрос что-то ваш не работает как надо
kaww
Цитата (Эли4ка @ 27.03.2019 - 13:01)
Но запрос что-то ваш не работает как надо

Работает так как требуется, разве нет? http://sqlfiddle.com/#!9/469eb7f/1
Эли4ка
так у меня же данные в одной таблице хранятся, я ведь дала ссылку на таблицу.
Zzepish
Эли4ка
Цитата
Вот хотелось бы обоснование.

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

VeRTak
Цитата
Смотря как педалить smile.gif Можно такой велосипед собрать, что и педали будут быстро крутиться, а вот прикладывать на php рекурсивные вещи которые завязаны на бд, я бы не советовал никогда

Ну, мб я просто не в теме )

Kusss
вот
	$categories = [];
$sql = "
SELECT
*
FROM
`test`
ORDER BY
`to_id`,
`id`
"
;
$result = $mysqli->query($sql);
while ($value = $result->fetch_assoc()) {

$categories[ $value['id'] ] = $value;
}


echo '<pre>';
$id = 7;
print_r( breadcrumb($id, $categories) );
$id = 6;
print_r( breadcrumb($id, $categories) );
echo '</pre>';


// Получаем массив для хлебных крошек
function breadcrumb($id, $categories = []){

if (count($categories) == 0)
return false;

$brc = [];

//Перебираем полученый массив с меню
for($i = 0; $i < count($categories); $i++){
//Проверяем что мы не нашли родителя и не массив пуст
if($id != 0 and !empty($categories[$id])){
//Ищим родителя
$brc[ $categories[$id]['id'] ] = $categories[$id]['name'];
$id = $categories[$id]['to_id'];
}
//Останавливаем цикл
else
break
;
}

//Возвращаем перевернутый массив с сохранением ключей
return array_reverse($brc, true);
}
и результат
Array
(
[1] => Дерево
[4] => Бумага
[7] => Книга
)
Array
(
[2] => Руда
[5] => Железо
[6] => Сталь
)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.