скопировать запись нескольких таблиц с зависимостью - PullRequest
1 голос
/ 25 января 2020
CREATE TABLE a (
    a_id SERIAL PRIMARY KEY,
    a_value varchar(255)
);
CREATE TABLE b (
    b_id SERIAL PRIMARY KEY,
    b_value varchar(255),
    a_id INT REFERENCES a(a_id) NOT NULL,
    UNIQUE (a_id, b_value)
);
CREATE TABLE c (
    c_id SERIAL PRIMARY KEY,
    c_value varchar(255),
    b_id INT REFERENCES b(b_id) NOT NULL,
    UNIQUE (b_id, c_value)
);

INSERT INTO a (a_value) VALUES ('a1'),('a2'),('a3');
INSERT INTO b (a_id, b_value) VALUES (1, 'b01'),(1, 'b02'),(2, 'b01'),(2, 'bbb'),(3, 'b3');
INSERT INTO c (b_id, c_value) VALUES (1, 'c1'),(1, 'c2'),(1, 'c3'),(2, 'c1'),(2, 'c2'),(2, 'c3'),(4, 'c2');

Как я могу скопировать запись (например, a_id = 1) в основную таблицу с другим значением, но с теми же записями зависимостей?

Как руководство

INSERT INTO a (a_value) SELECT 'copy_' || a_value FROM a RETURNING a_id;
--give a_id = 4;
INSERT INTO b (a_id, b_value) SELECT 4, b_value FROM b WHERE b.a_id = 1 RETURNING b_id;
--give b_id = 6 and 7
INSERT INTO c (b_id, c_value) SELECT 6, c_value FROM c WHERE c.b_id = 1;
INSERT INTO c (b_id, c_value) SELECT 7, c_value FROM c WHERE c.b_id = 2;

с двумя таблицами работают так:

WITH
a_ AS (
INSERT INTO a (a_value) SELECT 'copy_'||(SELECT COUNT(a_id) FROM a WHERE a_value LIKE 'copy_%')||'_'||a_value FROM a WHERE a_id = 1 RETURNING a_id
)
INSERT INTO b (a_id, b_value) 
    SELECT a_.a_id, b_value FROM a_, b WHERE b.a_id = 1 RETURNING b_id

но как копировать записи в таблице C? если будет четыре таблицы?

до

a_id | a_value
--------------
1    |  a1
2    |  a2
3    |  a3

b

b_id| a_id| b_value
--------------
1   |  1  |  b01
2   |  1  |  b02
3   |  2  |  b01
4   |  2  |  bbb
5   |  3  |  b3

c

c_id| b_id| c_value
--------------
1  |  1  |  c1
2  |  1  |  c2
3  |  1  |  c3
4  |  2  |  c1
5  |  2  |  c2
6  |  2  |  c3
7  |  4  |  c2

после

a

a_id | a_value
--------------
1    |  a1
2    |  a2
3    |  a3
4    |  copy_a3

b

b_id| a_id| b_value
--------------
1   |  1  |  b01
2   |  1  |  b02
3   |  2  |  b01
4   |  2  |  bbb
5   |  3  |  b3
6   |  4  |  b01
7   |  4  |  b02

c

c_id| b_id| c_value
--------------
1  |  1  |  c1
2  |  1  |  c2
3  |  1  |  c3
4  |  2  |  c1
5  |  2  |  c2
6  |  2  |  c3
7  |  4  |  c2
8  |  6  |  c1
9  |  6  |  c2
10 |  6  |  c3
11 |  7  |  c1
12 |  7  |  c2
13 |  7  |  c3

1 Ответ

0 голосов
/ 26 января 2020

Я добавляю столбец в таблицу B

 old_b_id INT REFERENCES b(b_id)

и делаю запрос как

WITH
a_ AS (
INSERT INTO a (a_value) SELECT 'copy_'||(SELECT COUNT(a_id) FROM a WHERE a_value LIKE 'copy_%')||'_'||a_value FROM a WHERE a_id = 3 RETURNING a_id
),
new_a AS(
SELECT b_id, a_.a_id FROM b, a_ WHERE b.a_id = 3
)
,b_ AS (
INSERT INTO b (a_id, b_value, old_b_id) SELECT new_a.a_id, b_value, new_a.b_id FROM new_a LEFT JOIN b USING(b_id) RETURNING b_id, old_b_id
)
INSERT INTO c (b_id, c_value) SELECT b_.b_id, c_value FROM c INNER JOIN b_ ON (c.b_id = b_.old_b_id)

Это работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...