【问题标题】:Use multiple rows from the same table in UPDATE of one row in another table在另一个表中的一行的 UPDATE 中使用同一表中的多行
【发布时间】:2013-03-26 01:55:40
【问题描述】:

我正在为 PostgreSQL (9.1) 使用 pgadmin,我有这个查询需要很长时间才能运行

update tableA a
set owner1_surname = (select owner_surname from owners_distinct b where a.owner1= b.owner),
owner1_othername   = (select owner_othername from owners_distinct b where a.owner1= b.owner),
owner2_surname     = (select owner_surname from owners_distinct b where a.owner2= b.owner),
owner2_othername   = (select owner_othername from owners_distinct b where a.owner2= b.owner),
owner3_surname     = (select owner_surname from owners_distinct b where a.owner3= b.owner),
owner3_othername   = (select owner_othername from owners_distinct b where a.owner3= b.owner)

不必一次又一次地从owners_distinct table 检索值,是否可以使用SELECT 检索列ownerowner_surnameowner_othername,然后在@ 上执行UPDATE 987654328@的列基于检查?

【问题讨论】:

    标签: sql postgresql sql-update postgresql-9.1


    【解决方案1】:

    这比我最初想象的要复杂,因为您想多次加入同一个表,而唯一的连接是更新后的表本身:

    UPDATE table_a a
        SET owner1_surname = b1.owner_surname
        ,owner1_othername  = b1.owner_othername
        ,owner2_surname    = b2.owner_surname
        ,owner2_othername  = b2.owner_othername
        ,owner3_surname    = b3.owner_surname
        ,owner3_othername  = b3.owner_othername
    FROM   table_a x
    LEFT   JOIN owners_distinct b1 ON b1.b.owner = x.owner1
    LEFT   JOIN owners_distinct b2 ON b2.b.owner = x.owner2 
    LEFT   JOIN owners_distinct b2 ON b3.b.owner = x.owner3
    WHERE  x.table_a_id = a.table_a_id
    

    其中table_a_idtable_a 的主键。通常您不必再次加入该表,但在这种情况下,您需要它来进行加入之前您可以链接到更新的表。

    我使用LEFT JOIN,以防止在owners_distinct 中找不到三个所有者之一时对一行的整个更新失败。

    数据库设计

    您确定需要table_a 中的所有冗余数据吗?规范化模式中的规范方法是仅存储foreign keysowner1owner2owner3),并在SELECT 中使用JOIN 按需获取名称的详细信息。完全删除您正在更新的所有列。当然,规则总是有例外的......

    没有唯一键?

    这不应该发生在开始。您应该添加一个代理主键,例如:

    ALTER TABLE table_a ADD table_a_id serial PRIMARY KEY;
    

    在相关答案中了解更多信息:
    Do I need a primary key for my table, which has a UNIQUE (composite 4-columns), one of which can be NULL?

    没有唯一键的解决方案

    无论如何,这里有一种方法可以使此更新不受任何唯一列的影响:

    UPDATE table_a a
        SET owner1_surname = b1.owner_surname
        ,owner1_othername  = b1.owner_othername
        ,owner2_surname    = b2.owner_surname
        ,owner2_othername  = b2.owner_othername
        ,owner3_surname    = b3.owner_surname
        ,owner3_othername  = b3.owner_othername
    FROM   (SELECT DISTINCT owner1, owner2, owner3 FROM table_a) x
    LEFT   JOIN owners_distinct b1 ON b1.b.owner = x.owner1
    LEFT   JOIN owners_distinct b2 ON b2.b.owner = x.owner2 
    LEFT   JOIN owners_distinct b2 ON b3.b.owner = x.owner3
    WHERE  x.owner1 = a.owner1
    AND    x.owner2 = a.owner2
    AND    x.owner3 = a.owner3;
    

    重点是:我们只需要(owner1, owner2, owner3)的每个组合一次。

    【讨论】:

    • @CCGooner:每个表都应该有一个主键。这个没有?无论哪种方式,任何独特的列组合都可以完成这项工作。如果需要,整行。只需避免可能是 NULL 的列。
    【解决方案2】:

    从 table_a 中选择所有者、所有者姓氏和所有者其他名称

    更新 table_a

     SET owner1_surname = b1.owner_surname
    ,owner1_othername  = b1.owner_othername
    ,owner2_surname    = b2.owner_surname
    ,owner2_othername  = b2.owner_othername
    ,owner3_surname    = b3.owner_surname
    ,owner3_othername  = b3.owner_othername
    

    【讨论】:

    • 我希望仅当 table_a.owner1=owners_distinct.owner 和 owner2surname、owner2othername 和 owner3surname、owner3othername 时才更新 owner1_surname、owner1_othername
    • 在此代码之前尝试输入此条件:IF table_a.owner1=owners_distinct.owner 和 owner2surname、owner2othername 和 owner3surname、owner3othername 相同
    猜你喜欢
    • 2014-11-08
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2011-02-22
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多