2

我正在为 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一次又一次地检索值,是否可以检索列ownerowner_surname并且owner_othername只需使用一次SELECT,然后根据检查执行UPDATEon列?tableA

4

2 回答 2

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_id的主键在哪里table_a。通常,您不必再次加入该表,但在这种情况下,您需要它进行加入,然后才能链接到更新的表。

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

数据库设计

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

没有唯一键?

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

ALTER TABLE table_a ADD table_a_id serial PRIMARY KEY;

相关答案中的更多信息:
我的表是否需要一个主键,它有一个 UNIQUE(复合 4 列),其中一个可以为 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)一次。

于 2013-03-26T02:12:17.483 回答
-1

从 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
于 2013-03-26T02:29:06.340 回答