使用JOIN条件更新SQL表

时间:2015-10-29 11:18:57

标签: sql postgresql

假设你有桌子:

CREATE TABLE TABLE1 (ID INTEGER PRIMARY KEY, VAL INT, CONDITION INT);
CREATE TABLE TABLE2 (ID INTEGER PRIMARY KEY, VAL INT, CONDITION INT);

有数据:

INSERT INTO TABLE1 VALUES (0, 0, 100);

INSERT INTO TABLE2 VALUES
(0, 2, 100),
(1, 1, 100),
(3, 3, 100)

此查询后TABLE1中的内容是什么?为什么?

UPDATE TABLE1 SET VAL = SOURCE.VAL 
FROM TABLE2 SOURCE 
WHERE TABLE1.CONDITION = SOURCE.CONDITION

我得到了:

0;2;100

这是否意味着RDBMS多次执行UPDATE操作并且我只看到最终结果?或者只更新VAL一次?

说明:

"Update on table1  (cost=270.68..562.65 rows=18818 width=24)"
"  ->  Merge Join  (cost=270.68..562.65 rows=18818 width=24)"
"        Merge Cond: (table1.condition = source.condition)"
"        ->  Sort  (cost=135.34..140.19 rows=1940 width=14)"
"              Sort Key: table1.condition"
"              ->  Seq Scan on table1  (cost=0.00..29.40 rows=1940 width=14)"
"        ->  Sort  (cost=135.34..140.19 rows=1940 width=14)"
"              Sort Key: source.condition"
"              ->  Seq Scan on table2 source  (cost=0.00..29.40 rows=1940 width=14)"

我使用了PostgreSQL。

3 个答案:

答案 0 :(得分:2)

来自documentation

  

目标行不应该从其他表连接到多个行。如果是,那么只有一个连接行将用于更新目标行,但是将使用哪一个不容易预测。

所以你看到的行为正是应该发生的事情。

答案 1 :(得分:1)

您的问题似乎是关于正在更新的表中存在多个匹配项时会发生什么。输出中只设置一个值。任意匹配行用于更新。

documentation解释了会发生什么:

  

备注

     

当存在FROM子句时,基本上发生的是   目标表连接到from_list中提到的表,和   连接的每个输出行代表一个更新操作   目标表。使用FROM时,应确保连接生成   每个要修改的行最多一个输出行。换句话说,一个   目标行不应该从另一行连接到多个行   表(一个或多个)。如果是,则只使用其中一个连接行   更新目标行,但不会轻易使用哪一行   可预测的。

     

由于这种不确定性,仅在其中引用其他表   子选择更安全,但通常更难阅读和慢   使用连接。

答案 2 :(得分:0)

这取决于目标。 在这种情况下,当涉及表时,它将选择单个记录匹配(主要是第一个)并使用它。 您可以通过在Table1上创建触发器来验证它,并标记记录更改的次数。 如果目标不是表而是变量,那么每行都会进行更新。例如,这是连接值的快速方法。