通过 postgresql 中的其他列值更新列值

Posted

技术标签:

【中文标题】通过 postgresql 中的其他列值更新列值【英文标题】:update column values by other column values in postgresql 【发布时间】:2018-07-05 23:02:03 【问题描述】:

我有什么

id  s_1     s_2      s_3      s_4     s_5     s_6     s_7      s_8

 ax    1      0         0       0       0        0       0       0
 bx    0      1         0       0       0        0       0       0
 cx    0      0         1       0       0        0       0       0
 dx    0      0         0       1       0        0       0       0
 ex    0      0         0       0       1        0       0       0
 fx    0      0         0       0       0        1       0       0
 gx    0      0         0       0       0        0       1       0
 hx    0      0         0       0       0        0       0       1

我正在尝试更新我的列值,如下所示。

如果我有 1,0,0,0,0,0,0,0,作为从 s1 到 s8 的列值,那么它应该更新为 1,0,1,0,1,0,1,0

如果我有 0,1,0,0,0,0,0,0 作为从 s1 到 s8 的列值,那么它应该更新为 0,1,1,0,1,0,1,0

如果我有 0,0,1,0,0,0,0,0 作为从 s1 到 s8 的列值,那么它应该更新为 0,0,1,0,1,0,1,0

如果我有 0,0,0,1,0,0,0,0 作为从 s1 到 s8 的列值,那么它应该更新为 0,0,0,1,1,0,1,0

如果我有 0,0,0,0,1,0,0,0,作为从 s1 到 s8 的列值,那么它应该更新为 0,0,0,0,1,0,1,0

如果我有 0,0,0,0,0,1,0,0 作为从 s1 到 s8 的列值,那么它应该更新为 0,0,0,0,1,1,1,0

如果我有 0,0,0,0,0,0,1,0,作为从 s1 到 s8 的列值,那么它应该更新为 0,0,0,0,0,0,1,0

如果我有 0,0,0,0,0,0,0,1 作为从 s1 到 s8 的列值,那么它应该更新为 0,0,0,0,0,0,0,1

输出如下所示

 id  s_1     s_2      s_3      s_4     s_5     s_6     s_7      s_8

 ax    1      0         1       0       1        0       1       0
 bx    0      1         1       0       1        0       1       0
 cx    0      0         1       0       1        0       1       0
 dx    0      0         0       1       1        0       1       0
 ex    0      0         0       0       1        0       1       0
 fx    0      0         0       0       1        1       1       0
 gx    0      0         0       0       0        0       1       0
 hx    0      0         0       0       0        0       0       1

【问题讨论】:

如果您使用 Greenplum,请不要添加 postgresql 标签 【参考方案1】:
UPDATE table_name AS o
   SET (s_1, s_2, s_3, s_4, s_5, s_6, s_7, s_8) = (n_1, n_2, n_3, n_4, n_5, n_6, n_7, n_8) 
  FROM (
       VALUES 
         (1,0,0,0,0,0,0,0, 1,0,1,0,1,0,1,0),
         (0,1,0,0,0,0,0,0, 0,1,1,0,1,0,1,0), 
         (0,0,1,0,0,0,0,0, 0,0,1,0,1,0,1,0), 
         (0,0,0,1,0,0,0,0, 0,0,0,1,1,0,1,0), 
         (0,0,0,0,1,0,0,0, 0,0,0,0,1,0,1,0),
         (0,0,0,0,0,1,0,0, 0,0,0,0,1,1,1,0),
         (0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0),
         (0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1)
       ) as n (
         s_1, s_2, s_3, s_4, s_5, s_6, s_7, s_8,
         n_1, n_2, n_3, n_4, n_5, n_6, n_7, n_8
       ) 
 WHERE (o.s_1, o.s_2, o.s_3, o.s_4, o.s_5, o.s_6, o.s_7, o.s_8) = (n.s_1, n.s_2, n.s_3, n.s_4, n.s_5, n.s_6, n.s_7, n.s_8)

【讨论】:

【参考方案2】:

我确信有一个单一的 SQL 更新解决方案,但下面的多语句更容易编写(和调试):

update my_table -- case 1: 1,0,0,0,0,0,0,0
  set s1 = 1, s2 = 0, s3 = 1, s4 = 0, s5 = 1, s6 = 0, s7 = 1, s8 = 0
  where s1 = 1 and s2 = 0 and s3 = 0 and s4 = 0 
    and s5 = 0 and s6 = 0 and s7 = 0 and s8 = 0;

那么,对于案例 2:

update my_table -- case 2: 0,1,0,0,0,0,0,0
  set s1 = 0, s2 = 1, s3 = 1, s4 = 0, s5 = 1, s6 = 0, s7 = 1, s8 = 0
  where s1 = 0 and s2 = 1 and s3 = 0 and s4 = 0 
    and s5 = 0 and s6 = 0 and s7 = 0 and s8 = 0;

您可以编写其余的情况(3、4、5、6、7 和 8)。

【讨论】:

是的。我正在尝试单个 SQL 更新解决方案,而不是编写多个 Sql 语句。 完全有可能做到这一点。当我需要添加两个 8 位整数并使用最少数量的晶体管来完成它(最佳解决方案)时,它让我想起了数字电路。如果你真的喜欢它,你需要为你拥有的八位中的每一个开发完整的真值表列表 (en.wikipedia.org/wiki/Truth_table)。如果您花几个小时,我很乐意看到您的最佳解决方案。

以上是关于通过 postgresql 中的其他列值更新列值的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:通过其他表中的值更新列值

通过选择 Pandas 中的其他列来更新条件列值

通过使用选择连接查询将 2 个列值相加来更新列值

MySQL - 根据更新其他表列值触发更新列值

如何将列值从存储过程中的另一个表更新到表中?

使用列值 postgresql 创建间隔