我有一个以下的PostgreSQL表:
CREATE TABLE users (
user_id INTEGER DEFAULT nextval('users_user_id_seq') NOT NULL,
user_old_id CHARACTER VARYING(36),
created_by INTEGER,
created_by_old character varying(36),
last_updated_by INTEGER,
last_updated_by_old character varying(36),
CONSTRAINT users_pkey PRIMARY KEY (user_id)
);
根据此表中的数据,我需要更新:
created_by
字段user_id
来自此表
其中created_by_old = user_old_id
请注意created_by_old
可以为NULL,因此在这种情况下必须避免。
last_updated_by
此表格中包含user_id
的字段
last_updated_by_old = user_old_id
行请注意last_updated_by_old
可以为NULL,因此在这种情况下必须避免。
这是一个示例数据:
实际
user_id | user_old_id | created_by | created_by_old | last_updated_by | last_updated_by_old
--------------------------------------------------------------------------------------------
1 | aaa | | ccc | | bbb
--------------------------------------------------------------------------------------------
2 | bbb | | ddd | | aaa
--------------------------------------------------------------------------------------------
3 | ccc | | | | ddd
--------------------------------------------------------------------------------------------
4 | ddd | | aaa | |
预期:
user_id | user_old_id | created_by | created_by_old | last_updated_by | last_updated_by_old
--------------------------------------------------------------------------------------------
1 | aaa | 3 | ccc | 2 | bbb
--------------------------------------------------------------------------------------------
2 | bbb | 4 | ddd | 1 | aaa
--------------------------------------------------------------------------------------------
3 | ccc | | | 4 | ddd
--------------------------------------------------------------------------------------------
4 | ddd | 1 | aaa | |
我认为它可以用子查询实现,但现在不能自己弄清楚如何实现这个查询。请帮忙。
答案 0 :(得分:1)
效率不高,但如果这不是问题,你可以这样做:
UPDATE users u
SET u.created_by = (SELECT t.user_id FROM users t
WHERE u.created_by_old = t.user_old_id),
u.last_updated_by = (SELECT s.user_id FROM users s
WHERE u.last_updated_by = s.user_old_id)
答案 1 :(得分:1)
如果您想要更高效的更新语句,可以使用派生表来获取您想要的信息作为更新语句的来源:
update users u1
set created_by = t.new_created_by,
last_updated_by = t.new_updated_by
from (
select u2.user_id, u2.user_old_id,
cr.user_id as new_created_by,
lu.user_id as new_updated_by
from users u2
left join users cr on cr.user_old_id = u2.created_by_old
left join users lu on lu.user_old_id = u2.last_updated_by_old
) t
where t.user_id = u1.user_id;
通常不应在from
子句中重复更新的目标表,但这种情况是一个罕见的例子,无法避免。
但如果user_old_id
也是唯一的,那么仅才会正常工作,而不仅仅是user_id
。