как скопировать дерево?

PG81
Дата: 20.04.2015 08:34:56
Здравствуйте!
есть деревянная табличка tab
с полями id, parent_id, name, type_id
и нужно в этой же таблице все записи, где type_id=1
скопировать и присвоить всем новым записям type_id=2.
Из-за деревянности таблицы получается это как-то непросто.
vyegorov
Дата: 20.04.2015 09:15:55
PG81,

SELECT id, parent_id,name,2 AS type_id
  FROM tab
 WHERE type_id=1;
Владимир СА
Дата: 20.04.2015 09:28:12
PG81
Здравствуйте!
есть деревянная табличка tab
с полями id, parent_id, name, type_id
и нужно в этой же таблице все записи, где type_id=1
скопировать и присвоить всем новым записям type_id=2.
Из-за деревянности таблицы получается это как-то непросто.
Скрипт бы таблицы...
Ограничения на поля есть ?
А то просто хочу и все...
Что пробовал сам ?
Какое сообщение об ошибке ?
PG81
Дата: 20.04.2015 10:30:06
Владимир СА,

я думал известная проблема))
+ Скрипт добавления таблицы и данных

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 загнать во временную таблицу, а потом уже в цикле как-то вставлять все это

мне показалось это как не эффективно, и поэтому я решил посоветоваться
p2.
Дата: 20.04.2015 11:23:03
PG81,

id+11, parent_id+11
Владимир СА
Дата: 20.04.2015 11:54:45
PG81
Владимир СА,

я думал известная проблема))
+ Скрипт добавления таблицы и данных

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-ы не должны пройти, т.к.
id integer NOT NULL DEFAULT nextval('tab_id_seq'::regclass)

Сначала надо убрать ссылку на сиквенс
DEFAULT nextval('tab_id_seq'::regclass)
Владимир СА
Дата: 20.04.2015 12:28:23
Или по одному INSERT-у вставлять... ориентируясь на результаты вставки... ID...
p2.
Дата: 20.04.2015 12:35:41
Владимир СА
Сначала надо убрать ссылку на сиквенс
DEFAULT nextval('tab_id_seq'::regclass)
Дефолт не констрейнт, чтобы молиться на него.
Владимир СА
Дата: 20.04.2015 12:45:49
p2.
Владимир СА
Сначала надо убрать ссылку на сиквенс
DEFAULT nextval('tab_id_seq'::regclass)
Дефолт не констрейнт, чтобы молиться на него.
Сиквенс все равно надо менять... он при дальнейших вставках даст сбой...
Владимир СА
Дата: 20.04.2015 13:45:56
PG81,
впринципе... записи вставятся...
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

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