更新 table 列,然后使用前者的更新值更新另一列。 MySQL / PostgreSQL 不同
Update a table column, then the other column with updated value of the former. MySQL / PostgreSQL differ
create table test (
id serial primary key,
c1 int,
c2 int
);
insert into test (c1,c2) values (1,1);
-- here (id, c1, c2) = (1, 1, 1)
update test set c1=2, c2=c1+2;
SELECT * FROM test ;
MySQL 给出 (1,2,4),Postgres 给出 (1,2,3)。
我希望 PostgreSQL 表现得像 MySQL,使用更新后的值而不是原始值。可能吗?否则,如果我在列上有索引并进行两次更新而不是一次更新,那么我就有不必要的 UPDATE = DELETE + INSERT(对于 PostgreSQL),并且工作量加倍。在特殊情况下,我实际上必须做 4 次更新而不是一次 :(。在 SQL 之外做加法很容易,但我有 SQL 相关函数。
N.B。据我所知, UPDATE = DELETE + INSERT 可能不是数字类型的情况,或者它们是否有索引?对于 varchars,它始终为真。
Postgres 是对的。根据 MySQL 文档:
The second assignment in the following statement sets col2 to the
current (updated) col1 value, not the original col1 value. The result
is that col1 and col2 have the same value. This behavior differs from
standard SQL.
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
我认为你不应该要求破坏 Postgres。
Postgres(和 ANSI)使用的逻辑很简单。在更新语句中,SET
左边的值指的是new记录;右边的值指的是 old 记录。作业的顺序并不重要。
MySQL 有不同的规则。
在 Postgres 中,您可以做这样的事情:
update test
set c1 = t1.new_c1, c2 = new_c1 + 2
from (select t1.*, 2 as new_c1
from test t1
) t1
where test.id = t1.id;
显然,对于一个简单的常量,这是多余的,但对于一个复杂的表达式,它可能是有意义的。另外,因为 JOIN
在主键上,所以对性能影响很小。
create table test (
id serial primary key,
c1 int,
c2 int
);
insert into test (c1,c2) values (1,1);
-- here (id, c1, c2) = (1, 1, 1)
update test set c1=2, c2=c1+2;
SELECT * FROM test ;
MySQL 给出 (1,2,4),Postgres 给出 (1,2,3)。
我希望 PostgreSQL 表现得像 MySQL,使用更新后的值而不是原始值。可能吗?否则,如果我在列上有索引并进行两次更新而不是一次更新,那么我就有不必要的 UPDATE = DELETE + INSERT(对于 PostgreSQL),并且工作量加倍。在特殊情况下,我实际上必须做 4 次更新而不是一次 :(。在 SQL 之外做加法很容易,但我有 SQL 相关函数。
N.B。据我所知, UPDATE = DELETE + INSERT 可能不是数字类型的情况,或者它们是否有索引?对于 varchars,它始终为真。
Postgres 是对的。根据 MySQL 文档:
The second assignment in the following statement sets col2 to the current (updated) col1 value, not the original col1 value. The result is that col1 and col2 have the same value. This behavior differs from standard SQL.
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
我认为你不应该要求破坏 Postgres。
Postgres(和 ANSI)使用的逻辑很简单。在更新语句中,SET
左边的值指的是new记录;右边的值指的是 old 记录。作业的顺序并不重要。
MySQL 有不同的规则。
在 Postgres 中,您可以做这样的事情:
update test
set c1 = t1.new_c1, c2 = new_c1 + 2
from (select t1.*, 2 as new_c1
from test t1
) t1
where test.id = t1.id;
显然,对于一个简单的常量,这是多余的,但对于一个复杂的表达式,它可能是有意义的。另外,因为 JOIN
在主键上,所以对性能影响很小。