我有两个以下表格的表格(即每个foo都链接到一个条形图).
CREATE TABLE foo (
id INTEGER PRIMARY KEY,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
...,
bar_id INTEGER UNIQUE NOT NULL,
FOREIGN key (bar_id) REFERENCES bar(id)
);
CREATE TABLE bar (
id INTEGER PRIMARY KEY,
z INTEGER NOT NULL,
...
);
Run Code Online (Sandbox Code Playgroud)
foo使用嵌套查询复制满足特定条件的行很容易:
INSERT INTO foo (...) (SELECT ... FROM foo WHERE ...)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何bar为每一行制作相关行的副本foo并将id bar插入新foo行.有没有办法在单个查询中执行此操作?
期望结果的具体例子:
-- Before query:
foo(id=1,x=3,y=4,bar_id=100) ..... bar(id=100,z=7)
foo(id=2,x=9,y=6,bar_id=101) ..... bar(id=101,z=16)
foo(id=3,x=18,y=0,bar_id=102) ..... bar(id=102,z=21)
-- Query copies …Run Code Online (Sandbox Code Playgroud) 在架构更改后,我必须在Postgres DB中迁移大量现有数据.
在旧模式中,country属性将存储在users表中.现在,country属性已移至单独的地址表中:
users:
country # OLD
address_id # NEW [1:1 relation]
addresses:
id
country
Run Code Online (Sandbox Code Playgroud)
模式实际上更复杂,地址不仅包含国家/地区.因此,每个用户都需要拥有自己的地址(1:1关系).
迁移数据时,我在插入地址后在users表中设置外键时遇到问题:
INSERT INTO addresses (country)
SELECT country FROM users WHERE address_id IS NULL
RETURNING id;
Run Code Online (Sandbox Code Playgroud)
如何传播插入行的ID并在users表中设置外键引用?
到目前为止,我能想出的唯一解决方案是在地址表中创建一个临时的user_id列,然后更新address_id:
UPDATE users SET address_id = a.id FROM addresses AS a
WHERE users.id = a.user_id;
Run Code Online (Sandbox Code Playgroud)
然而,事实证明这非常慢(尽管在users.id和addresses.user_id上都使用了索引).
users表包含大约300万行,其中300k缺少相关地址.
有没有其他方法可以将派生数据插入到一个表中,并在另一个表中设置插入数据的外键引用(不更改架构本身)?
我正在使用Postgres 8.3.14.
谢谢
我现在通过使用Python/sqlalchemy脚本迁移数据来解决问题.事实证明(对我来说)比用SQL尝试更容易.不过,如果有人知道在Postgres SQL中处理INSERT语句的RETURNING结果的方法,我会感兴趣.
我只是在编写一个看起来或多或少像这样的复杂更新查询:
update table join
(select y, min(x) as MinX
from table
group by y) as t1
using (y)
set x = x - MinX
Run Code Online (Sandbox Code Playgroud)
这意味着变量x是基于子查询,也处理变量更新x-但可能不是这个x已经由运行update命令进行修改?这不是问题吗?我的意思是,在正常的编程中,你通常必须明确地处理它,即从旧值将新值存储到其他地方,并在完成作业后,用new替换旧值...但SQL数据库将如何执行此操作?
我对单一观察或实验不感兴趣.我想有一个来自docs或sql标准的片段,它会说明在这种情况下定义的行为是什么.我正在使用MySQL,但答案也适用于其他PostgresQL,Oracle等,特别是对于SQL标准一般都很感激.谢谢!