-
как избавиться от with recursive в запросе:
BEGIN
RETURN query
WITH RECURSIVE R AS
(SELECT id
FROM accounts.groups WHERE id=(_id)
UNION ALL
SELECT accounts.groups.id
FROM accounts.groups
JOIN R
ON accounts.groups.parent_id = r.id
)
SELECT *FROM R;
END;
-
Уточните пожалуйста, вы хотите тот же результат, не используя WITH RECURSIVE ?
-
именно так.
-
быстрее без введения дополнительных полей никак. А вот если поле добавить текстовое и заполнять его таким образом: 1. родитель 1.1. - 1 потомок 1 уровня 1.2. - 2 потомок 1 уровня 1.1.1. - 1 потомок 2 уровня То получить список потомков по родителю select * from table where hierarchy like '1.%' Ну, а дальше на сколько фантазии хватит.
-
изменение структуры таблицы не планировалось . иерархия у нас организована с помощью полей id, parent_id. можно ли организовать функцию с выводом дерева с помощью цикла?
-
да. А чем with recursive не устраивает? У вас будет входящий Id родителя чтобы получить потомков или нужно все дерево?
-
Если все дерево, то 1. Перед циклом наполняете временную таблицу temp записями из своей table 2. В цикле объединяете вновь добавленные записи таблицы temp со своей таблицей и результат вставляете опять в temp и так пока объединяется.
-
Если входящий Id, то в п.1. наполняем не всеми записями, а только отобранной по id
-
можно ли организовать функцию с выводом дерева с помощью цикла?
тебе какая разница где будет рекурсия, в постгрессе или в цикле?
это к тому, что придумав иерархическую организацию данных, надо юзать рекурсию по полной, а не спрашивать как от нее избавиться.
-
как будет выглядеть подобный запрос в цикле?
-
он будет выглядеть как корова обутая в седло
-
мне нужна корова :) почему этот вариант возвращает только вершину дерева? CREATE OR REPLACE FUNCTION accounts.without_recursive(_id uuid) RETURNS table (id uuid, parent_id uuid, name character varying(64))AS
$BODY$
DECLARE
r uuid;
BEGIN
--return query
FOR r in SELECT id, parent_id, name FROM accounts.groups WHERE id = _id
LOOP
return query
select ag.id, ag.parent_id, ag.name from accounts.groups as ag join r ON ag.id = r.parent_id;
RETURN NEXT;
END LOOP;
RETURN;
END;
$BODY$
LANGUAGE 'plpgsql' STABLE STRICT
-
ну iop, раскоментарь первый ретурн. пропала и сама вершина?
и какой вывод?
-
хорошо, я поняла. тема названа не верно. нужно было написать не 'как избавиться от рекурсии' а как можно по-другому запросить данные.
> iop
а вот что не так с ретурнами я не догоняю.
-
если после раскоментаренного первого ретурна пропадает вершина иерархии, то это значит, что когда он закоментарен, то ты вылетаешь из цикла по ретурну на первой же итерации. и в выборке только вершина дерева.
-
Че-то я не понял, в чем проблема с with recursive ? К сожалению синтаксиса postgresql я не знаю. Но по ходу 1 что увидел, Вам нужно объединять вновь добавленные записи а не все. т.е. на 1 итерации все, допустим от 1...100, на второй уже от 101 до 120.
-
если в базе сделать логическую ошибку, то используя в запросе with recursive можно повесить базу. этот код выбирает родителя и первую ветку детей, остальное не выводит. почему??? CREATE OR REPLACE FUNCTION accounts.without_recursive(_id uuid) RETURNS table (id uuid, parent_id uuid, name character varying(64))AS
$BODY$
DECLARE
row_ record;
BEGIN
RETURN query
--возвращаем первую ветку дерева
SELECT us.id, us.parent_id, us.name FROM accounts.groups us WHERE us.id = _id;
--возвращаем детей
FOR row_ IN SELECT us.id, us.parent_id, us.name FROM accounts.groups us WHERE us.id = _id
LOOP
RETURN query
SELECT r.id, r.parent_id, r.name FROM accounts.groups AS r WHERE r.parent_id =row_.id;
RETURN NEXT;
END LOOP;
RETURN;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
-
короче. без рекурсии у тебя ничего не получится. даже если однажды из этой функции вылезет вторая ветка детей. но так как рекурсией можно повесить вашу кривую иерархию,
то вывод простой
спиливать дерево и клепать плоские таблицы заточенные на N поколений вложенности. не больше.
-
хотя если дерево на id + parent_id то как его можно зациклить?
простой вариант когда id = parent_id
других вроде нет, а этот вычищается на раз.
-
kate158 © (12.10.16 17:14) [16] Ничего не понимаю, а где временная таблица?
|