【问题标题】:copy record some tables with dependence复制记录一些有依赖关系的表
【发布时间】:2020-01-25 19:25:18
【问题描述】:
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_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

【问题讨论】:

  • 你试过WITH a AS ( INSERT INTO a ...), b AS (INSERT INTO b ...) INSERT INTO c...吗?
  • 在 B 中插入新的 2 行,例如 2 行,a_id = 1:在 C 中插入 6 行,例如 b_id IN (1,2)
  • 所以这里的结果是:dbfiddle.uk/… 是您对两个表的选择所期望的吗?
  • 是的,但我也想复制表 C 中的记录,其中包含指向表 B 中新条目的链接

标签: sql postgresql sql-insert


【解决方案1】:

我在表 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)

成功了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多