powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / как скопировать дерево?
18 сообщений из 18, страница 1 из 1
как скопировать дерево?
    #38940297
PG81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!
есть деревянная табличка tab
с полями id, parent_id, name, type_id
и нужно в этой же таблице все записи, где type_id=1
скопировать и присвоить всем новым записям type_id=2.
Из-за деревянности таблицы получается это как-то непросто.
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940315
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PG81,

Код: sql
1.
2.
3.
SELECT id, parent_id,name,2 AS type_id
  FROM tab
 WHERE type_id=1;
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940319
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PG81Здравствуйте!
есть деревянная табличка tab
с полями id, parent_id, name, type_id
и нужно в этой же таблице все записи, где type_id=1
скопировать и присвоить всем новым записям type_id=2.
Из-за деревянности таблицы получается это как-то непросто. Скрипт бы таблицы...
Ограничения на поля есть ?
А то просто хочу и все...
Что пробовал сам ?
Какое сообщение об ошибке ?
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940376
PG81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир СА,

я думал известная проблема))
Скрипт добавления таблицы и данных
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
CREATE SEQUENCE public.tab_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
  
CREATE TABLE public.tab
(
  id integer NOT NULL DEFAULT nextval('tab_id_seq'::regclass), -- Код
  parent_id integer, -- Код родителя
  name character varying(1000), -- Наименование
  type_id integer,
  CONSTRAINT tab_pkey PRIMARY KEY (id),
  CONSTRAINT tab_parent_id_fkey FOREIGN KEY (parent_id)
      REFERENCES public.tab (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
  OIDS=FALSE
);

insert into tab(id,parent_id,name,type_id)values(1,null,'дерево1',1);
insert into tab(id,parent_id,name,type_id)values(2,null,'дерево2',1);
insert into tab(id,parent_id,name,type_id)values(3,1,'дерево11',1);
insert into tab(id,parent_id,name,type_id)values(4,1,'дерево12',1);
insert into tab(id,parent_id,name,type_id)values(5,4,'дерево121',1);
insert into tab(id,parent_id,name,type_id)values(6,4,'дерево122',1);
insert into tab(id,parent_id,name,type_id)values(7,1,'дерево13',1);
insert into tab(id,parent_id,name,type_id)values(8,2,'дерево21',1);
insert into tab(id,parent_id,name,type_id)values(9,2,'дерево22',1);
insert into tab(id,parent_id,name,type_id)values(10,2,'дерево23',1);
insert into tab(id,parent_id,name,type_id)values(11,2,'дерево24',1);




Ну вот... а теперь нужно все эти записи еще раз добавить в эту же таблицу только поставить type_id проставить 2
соответственно поменяются ID и Parent_id нужно уже новые проставлять.

у меня пока получилось для 2х-уровнего джерева (добавляем корень, потом каждому корню его детей с уже новым ID корня)
для многоуровнего дерева по идее нужно делать так, нужно все записи, где type_id=1 загнать во временную таблицу, а потом уже в цикле как-то вставлять все это

мне показалось это как не эффективно, и поэтому я решил посоветоваться
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940429
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PG81,

id+11, parent_id+11
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940449
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PG81Владимир СА,

я думал известная проблема))
Скрипт добавления таблицы и данных
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
CREATE SEQUENCE public.tab_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
  
CREATE TABLE public.tab
(
  id integer NOT NULL DEFAULT nextval('tab_id_seq'::regclass), -- Код
  parent_id integer, -- Код родителя
  name character varying(1000), -- Наименование
  type_id integer,
  CONSTRAINT tab_pkey PRIMARY KEY (id),
  CONSTRAINT tab_parent_id_fkey FOREIGN KEY (parent_id)
      REFERENCES public.tab (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
  OIDS=FALSE
);

insert into tab(id,parent_id,name,type_id)values(1,null,'дерево1',1);
insert into tab(id,parent_id,name,type_id)values(2,null,'дерево2',1);
insert into tab(id,parent_id,name,type_id)values(3,1,'дерево11',1);
insert into tab(id,parent_id,name,type_id)values(4,1,'дерево12',1);
insert into tab(id,parent_id,name,type_id)values(5,4,'дерево121',1);
insert into tab(id,parent_id,name,type_id)values(6,4,'дерево122',1);
insert into tab(id,parent_id,name,type_id)values(7,1,'дерево13',1);
insert into tab(id,parent_id,name,type_id)values(8,2,'дерево21',1);
insert into tab(id,parent_id,name,type_id)values(9,2,'дерево22',1);
insert into tab(id,parent_id,name,type_id)values(10,2,'дерево23',1);
insert into tab(id,parent_id,name,type_id)values(11,2,'дерево24',1);




Ну вот... а теперь нужно все эти записи еще раз добавить в эту же таблицу только поставить type_id проставить 2
соответственно поменяются ID и Parent_id нужно уже новые проставлять.

у меня пока получилось для 2х-уровнего джерева (добавляем корень, потом каждому корню его детей с уже новым ID корня)
для многоуровнего дерева по идее нужно делать так, нужно все записи, где type_id=1 загнать во временную таблицу, а потом уже в цикле как-то вставлять все это

мне показалось это как не эффективно, и поэтому я решил посоветоватьсяINSERT-ы не должны пройти, т.к.
Код: sql
1.
id integer NOT NULL DEFAULT nextval('tab_id_seq'::regclass)


Сначала надо убрать ссылку на сиквенс
Код: sql
1.
DEFAULT nextval('tab_id_seq'::regclass)
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940497
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или по одному INSERT-у вставлять... ориентируясь на результаты вставки... ID...
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940504
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир САСначала надо убрать ссылку на сиквенс
Код: sql
1.
DEFAULT nextval('tab_id_seq'::regclass)

Дефолт не констрейнт, чтобы молиться на него.
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940512
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p2.Владимир САСначала надо убрать ссылку на сиквенс
Код: sql
1.
DEFAULT nextval('tab_id_seq'::regclass)

Дефолт не констрейнт, чтобы молиться на него.Сиквенс все равно надо менять... он при дальнейших вставках даст сбой...
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940574
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PG81,
впринципе... записи вставятся...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
WITH RECURSIVE temp1
(id, parent_id, name, LEVEL ) AS (
SELECT T1.id, T1.parent_id, T1.name, 1
    FROM tab T1 
	WHERE T1.parent_id IS NULL
union
select T2.id, T2.parent_id, T2.name ,LEVEL + 1
     FROM tab T2 
INNER JOIN temp1 ON( temp1.id = T2.parent_id)
)
insert into tab (id, parent_id, name,type_id)
select id+11 as id,  parent_id+11 as parent_id, name, 2 as type_id
from temp1


Но надо редактировать сиквенс, как я сообщал...
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940657
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир СА
Код: sql
1.
WITH RECURSIVE temp1

a recursive зачем?!
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940679
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p2.Владимир СА
Код: sql
1.
WITH RECURSIVE temp1

a recursive зачем?!Я просто из примера взял... и смоделировал на данную таблицу...
все отработало хорошо...
Ну, если не надо, так не надо...
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940708
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p2.Владимир СА
Код: sql
1.
WITH RECURSIVE temp1

a recursive зачем?!патамушта гладиолус


ну вы, блин, даёте.
это же отбор поддеревьев для переноса.

вот взяли "только нужные корешки", обошли всё от них (ну там еще какой-то фильтр забыли WHERE type_id=1; --авно вапрос )
и только требуемое и пересадили.

а то, что конкретно в тест--кейсе больше ничего и нет -- это не факт.

мне тут больше интересно - может ли дерево перемежаться -- одна ветка type_id=1;, а вторая -- совсем даже напротив type_id=2; а третья -- так и вообще type_id=0; -- и что тогда аффтар будет делать. пересаживать дерево целиком, или вырезку из оного ? а оно и не срастётся
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940735
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqну там еще какой-то фильтр забыли WHERE type_id=1; --авно вапрос ) В присутствие дырок в дереве как бы думать придется, но это к автору... Гадалки склоняются не к WHERE, а CASE.
А пока он не обременен раздумьями, нужно ли изобретать сложности?
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940745
PG81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант Владимира
Владимир САPG81,
впринципе... записи вставятся...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
WITH RECURSIVE temp1
(id, parent_id, name, LEVEL ) AS (
SELECT T1.id, T1.parent_id, T1.name, 1
    FROM tab T1 
	WHERE T1.parent_id IS NULL
union
select T2.id, T2.parent_id, T2.name ,LEVEL + 1
     FROM tab T2 
INNER JOIN temp1 ON( temp1.id = T2.parent_id)
)
insert into tab (id, parent_id, name,type_id)
select id+11 as id,  parent_id+11 as parent_id, name, 2 as type_id
from temp1


Но надо редактировать сиквенс, как я сообщал...



такой вариант не подойдет если кто-то еще в этот же момент будет копировать такое же дерево
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940750
PG81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

Что вы имеете ввиду "дерево перемежаться"?
Если как я понял, что ветки одного типа могут ссылаться на ветки другого типа, то такого по моим условиям не может быть никогда.
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940758
g2099599
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PG81,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
with foo as (
	select nextval('tab_id_seq'::regclass) as new_id, * from tab t where t.type_id = 1
)
select 
	id,
	parent_id,
	name,
	type_id, 
	new_id, 
	(select new_id from  foo fp where fp.id = f.parent_id )  as new_parent_id 
from foo f 
...
Рейтинг: 0 / 0
как скопировать дерево?
    #38940775
PG81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
g2099599,

Спасибо! Подходит!
Блин вот как такие штуки придумывать?))
элементарно же, когда уже готово
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / как скопировать дерево?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]