【问题标题】:Update a table column, then the other column with updated value of the former. MySQL / PostgreSQL differ更新一个表列,然后用前者的更新值更新另一列。 MySQL / PostgreSQL 不同
【发布时间】:2016-11-12 12:44:43
【问题描述】:
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 次更新而不是 1 次 :(。在 SQL 之外进行添加很容易,但我有 SQL 相关的函数。

注意据我记得, UPDATE = DELETE + INSERT 可能不是数字类型的情况,或者如果它们有索引?对于 varchars,它总是正确的。

【问题讨论】:

  • 既然你给 c1 赋值了,为什么不c1 = 2, c2=2+2呢?
  • 因为就像我写的那样,这只是一个例子,实际上我在这个地方使用了SQL函数而不是加法。我可以这样做:c1=f(c1), c2 = f2(f(c1)), 写多余的东西.. 但想知道是否有更好的解决方案。
  • 好问题。找不到关于 UPDATE 的 SQL 标准行为(谷歌搜索 SQL standard update source

标签: mysql sql postgresql multiple-columns


【解决方案1】:

Postgres 是对的。根据 MySQL 文档:

以下语句中的第二个赋值将 col2 设置为 当前(更新) col1 值,而不是原始 col1 值。结果 是 col1 和 col2 具有相同的值。 这种行为不同于 标准 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 位于主键上,因此对性能几乎没有影响。

【讨论】:

  • 在我发现这种 MySQL/PostgreSQL 差异之前,我已经看到了这些类型的 SQL,并怀疑它们的使用可能是有原因的 :)
猜你喜欢
  • 2015-03-23
  • 2014-12-08
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2014-09-01
  • 2012-11-08
相关资源
最近更新 更多