从子查询更新PostgreSQL

从子查询更新PostgreSQL,postgresql,Postgresql,我有以下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_up

我有以下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)
);
根据此表中的数据,我需要更新:

为此表中的每一行创建具有用户id的\u by字段 其中created_by_old=user_old_id请注意,created_by_old可以为空,因此在这种情况下必须避免

上次\u使用此表中的用户\u id为每个 last_updated_by_old=用户_old_id的行请注意,last_updated_by_old可以为空,因此在这种情况下必须避免

这是一个示例数据:

实际:

预期:


我认为它可以通过一个子查询来实现,但我现在还不知道如何实现这个查询。请帮助。

效率不太高,但如果这不是问题,您可以这样做:

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)

效率不太高,但如果这不是问题,您可以这样做:

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)

如果需要更高效的update语句,可以使用派生表获取所需信息作为update语句的源:

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子句中不应重复更新的目标表,但这种情况是一个罕见的无法避免的例子

但这只有在用户旧id也是唯一的情况下才能正常工作,而不仅仅是用户id


联机示例:

如果您想要更高效的update语句,可以使用派生表获取所需信息作为update语句的源:

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子句中不应重复更新的目标表,但这种情况是一个罕见的无法避免的例子

但这只有在用户旧id也是唯一的情况下才能正常工作,而不仅仅是用户id


在线示例:

请提供数据样本和预期输出。您到目前为止尝试了什么?@sagi我已用样本数据和预期结果更新了我的问题请提供数据样本和预期输出。您到目前为止尝试了什么?@sagi我已用样本数据和预期结果更新了我的问题谢谢。请注意,在某些行中,created_by_old或last_updated_by_old可以为空,因此在这种情况下必须避免更新相应的字段。如何更新此查询以支持此案例?为什么?如果为NULL,那么结果也将为NULL@亚历山大·诺伊德汉克斯。我还尝试了这个查询updateusers u SET u.created\u by=SELECT t.user\u id FROM users t其中u.created\u by\u old=t.user\u old\u id,u.last_updated_by=从用户s中选择s.user_id,其中u.last_updated_by_old=s.user_old_id,但失败时出现以下错误:错误:关系用户的u列不存在第1行:更新用户u设置u.created_by=从使用中选择t.user_id…我已将u.created_by更新为simple created_by,现在一切正常!非常感谢。谢谢请注意,在某些行中,created_by_old或last_updated_by_old可以为空,因此在这种情况下必须避免更新相应的字段。如何更新此查询以支持此案例?为什么?如果为NULL,那么结果也将为NULL@亚历山大·诺伊德汉克斯。我还尝试了这个查询updateusers u SET u.created\u by=SELECT t.user\u id FROM users t其中u.created\u by\u old=t.user\u old\u id,u.last_updated_by=从用户s中选择s.user_id,其中u.last_updated_by_old=s.user_old_id,但失败时出现以下错误:错误:关系用户的u列不存在第1行:更新用户u设置u.created_by=从使用中选择t.user_id…我已将u.created_by更新为simple created_by,现在一切正常!非常感谢。