1

我有两张桌子

junk=# select * from t;                                                                                                                                
   name   | intval 
----------+--------
 bar2  |      2
 bar3  |      3
 bar4  |      4
(3 rows)

junk=# select * from temp;                                                                                                                             
 id |    name    | intval 
----+------------+--------
  1 | foo   |      0
  2 | foo2  |      2
  3 | foo3  |      3
  4 | foo4  |      4
  5 | foo5  |      5
(5 rows)

现在,我想使用 from 中的值table t来更新table temp. 基本上,我想用 bar2、bar3 和 bar4 替换 temp 中第二、第三和第四个值中的名称列。

我使用 COPY 语句创建了表 t。我正在做批量更新,我正在尝试优化它。

所以,我得到这个错误。我认为这是非常基本的一个。

junk=# UPDATE temp FROM t SET name=t.name FROM t WHERE intval=t.intval;
ERROR:  syntax error at or near "FROM"
LINE 1: UPDATE temp FROM t SET name=t.name FROM t WHERE intval=t.int...
                    ^
junk=# 

现在,这行得通。

UPDATE test SET name=t.name FROM t WHERE test.intval=t.intval
4

1 回答 1

2

摆脱你的第一个 FROM t 子句。

FROM 必须在 SET 之后,而不是之前,它只会影响 WHERE 子句。SET 必须使用子查询来完成。

您完成的代码是:

UPDATE temp SET name=(SELECT t.name FROM t WHERE temp.intval = t.inval);

PostgreSQL 有一些方法可以优化这一点,所以它不像你只是在做一个巨大的嵌套循环连接(并根据连接条件从堆中一遍又一遍地查找一行)。

编辑:添加计划以显示我们实际上并没有对第一个表上的每一行的第二个表进行顺序扫描。

下面是一个示例,它使用来自另一个表的 group-by 更新一个表中的 172 行:

mtech_test=# explain analyze
update ap
set amount = (select sum(amount) from acc_trans ac where ac.trans_id = ap.id) + 1;
                                                                 QUERY PLAN 

--------------------------------------------------------------------------------
---------------------------------------------------------------------
Update on ap  (cost=0.00..3857.06 rows=229 width=231) (actual time=39.074..39.0
   74 rows=0 loops=1)
 ->  Seq Scan on ap  (cost=0.00..3857.06 rows=229 width=231) (actual time=0.050..28.444 rows=172 loops=1)
     SubPlan 1
       ->  Aggregate  (cost=16.80..16.81 rows=1 width=5) (actual time=0.109..0.110 rows=1 loops=172)
             ->  Bitmap Heap Scan on acc_trans ac  (cost=4.28..16.79 rows=4 width=5) (actual time=0.075..0.102 rows=4 loops=172)
                   Recheck Cond: (trans_id = ap.id)
                   ->  Bitmap Index Scan on acc_trans_trans_id_key  (cost=0.00..4.28 rows=4 width=0) (actual time=0.006..0.006 rows=4 loops=172)
                         Index Cond: (trans_id = ap.id)
Trigger for constraint ap_entity_id_fkey: time=69.532 calls=172
Trigger ap_audit_trail: time=391.722 calls=172
Trigger ap_track_global_sequence: time=1.954 calls=172
Trigger check_department: time=111.301 calls=172
Total runtime: 612.001 ms
(13 rows)

`

于 2012-08-30T04:02:46.413 回答