用于更新复合键中的列的 SQL 查询

标签 sql postgresql

我有一个像这样的 3 列的表

CREATE TABLE my_table (
  A_id INTEGER NOT NULL,
  B_id INTEGER NOT NULL,
  C CHARACTER VARYING(50) NOT NULL,
  PRIMARY KEY (A_id, B_id, C)
);

我必须用其他值更新 B_id 列中的某些值。 为此我尝试了这个查询

UPDATE my_table
SET B_id = 10
WHERE B_id = 20

但问题是这给了我一个“重复键值违反唯一约束

因为在某些地方表有这样的数据

A_id, B_id, C
1,     10,  a
1,     20,  a  ## this row seems to cause constraint problem
1,     20,  b
2,     20,  a
2,     20,  b 

我想让上面的数据变成这样

  A_id,  B_id,  C
    1,     10,  a
    1,     10,  b
    2,     10,  a
    2,     10,  b 

所以一般来说,如果组合键已经存在,则删除值为 20 的组合键,否则更新值。 感谢期待!

最佳答案

...如果组合键已经存在则忽略...

如果 ignore 表示:不更新,那么您可以使用 exists(tuple_with _new_values in the same table),如下所示:


UPDATE my_table mt
SET B_id = 10
WHERE mt.B_id = 20
AND NOT EXISTS ( SELECT *
        FROM my_table nx        -- same table
        WHERE nx.A_id = mt.A_id -- same value
        AND nx.B_id = 10        -- new value
        AND nx.C_id = mt.C_id   -- same value
        );

[更新] 问题改变后。您可以使用 CTE 组合两个操作:

  • 首先:删除更新会冲突的记录
  • 第二:更新删除的记录

WITH del AS ( -- delete tuples for which UPDATE would cause a conflict
        DELETE FROM my_table mt
        WHERE mt.B_id = 20
        AND EXISTS ( SELECT *
                FROM my_table nx
                WHERE nx.A_id = mt.A_id
                AND nx.B_id = 10
                AND nx.C_id = mt.C_id
                )
        RETURNING *
        )
UPDATE my_table upd -- UPDATE the records that were not deleted
SET B_id = 10
WHERE upd.B_id = 20
AND NOT EXISTS ( SELECT *
        FROM del
        WHERE del.A_id = upd.A_id
        AND del.B_id = upd.B_id
        AND del.C_id = upd.C_id
        );

关于用于更新复合键中的列的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44256902/

相关文章:

MySQL数据库表

mysql - 在连接表列上优化 ORDER BY COALESCE

php - Phalcon在模型中执行sql查询

PostgreSQL 可调用语句 : Malformed function or procedure escape syntax at offset 6

java - 无法更新 PostgreSQL 表中的字段

postgresql - 如何将参数传递给用 PL/pgSQL 编写的查询?

sql - 在 T-SQL 中组合名字、中间名首字母、姓氏和后缀(无多余空格)

events - Postgres : Post statement (or insert) asynchronous, 非阻塞处理

regex - 仅搜索字符串中的特定单词,不包括介于两者之间的任何内容

mysql - GROUP_CONCAT() 之类的函数返回不匹配的字段?