简体   繁体   English

如何使用PostgreSQL Upsert使用INSERT ON CONFLICT语句在不同的位置条件下更新多列

[英]How to do multiple columns update on different where condition using PostgreSQL Upsert Using INSERT ON CONFLICT statement

Suppose I have a table like this 假设我有一张这样的桌子

create schema test;
CREATE TABLE test.customers (
customer_id serial PRIMARY KEY,
name VARCHAR UNIQUE,
email VARCHAR NOT NULL,
active bool NOT NULL DEFAULT TRUE,
is_active_datetime                   TIMESTAMP(3) NOT NULL DEFAULT'1900-01-01T00:00:00.000Z'::timestamp(3)
updated_datetime                     TIMESTAMP(3) NOT NULL DEFAULT '1900-01-01T00:00:00.000Z'::timestamp(3),
);

Now If i want to update email on conflict name 现在,如果我想更新有关冲突name email

WHERE $tableName.updated_datetime < excluded.updated_datetime

and i want to update is_active_datetime on conflict name but that condition for this update is where active flag has changed. 我想更新冲突name上的is_active_datetime ,但此更新的条件是活动标志已更改。

WHERE customer.active != excluded.active

basically want to track when active status is changed. 基本上想跟踪活动状态何时更改。 so can I do that in single statement like this 所以我可以在这样的单个语句中做到这一点

Initial insert : 初始插入:

insert  INTO test.customers (NAME, email)
VALUES
('IBM', 'contact@ibm.com'),
(
'Microsoft',
'contact@microsoft.com'
 ),
(
 'Intel',
 'contact@intel.com'
);

To achieve my purpose I am trying something like this : 为了实现我的目的,我正在尝试这样的事情:

select * from test.customers;

INSERT INTO customers (name, email)
VALUES
(
'Microsoft',
'hotline@microsoft.com'
)
ON CONFLICT (name)
DO
UPDATE
SET customers.email = EXCLUDED.email
WHERE $tableName.updated_datetime < excluded.updated_datetime
on CONFLICT (name)
do
update
set is_active_datetime = current_timestamp()
WHERE customer.active != excluded.active ;

Is it possible to do this ? 是否有可能做到这一点 ? How to do this using this method. 如何使用此方法执行此操作。

You could update multiple columns with CASE conditions in a single DO UPDATE clause . 您可以在单个DO UPDATE clause使用CASE条件更新多个列。

INSERT INTO customers  (
    name
    ,email
    ,updated_datetime
    )
VALUES (
    'Microsoft'
    ,'hotline@microsoft.com'
    ,now()
    ) ON CONFLICT(name) DO

UPDATE
SET email = CASE 
        WHEN customers.updated_datetime < excluded.updated_datetime
            THEN excluded.email
        ELSE customers.email --default when condition not satisfied
        END
    ,is_active_datetime = CASE 
        WHEN customers.active != excluded.active
            THEN current_timestamp
        ELSE customers.is_active_datetime
    END;

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Postgres upsert 使用冲突 - 冲突条件下的多个字段 - Postgres upsert using on conflict - multiple fields in on conflict condition PostgreSQL Upsert(On Conflict),在Insert和Update中具有相同的值 - PostgreSQL Upsert (On Conflict) with same values in Insert and Update PostgreSQL UPSERT(插入...在冲突更新中)失败 - PostgreSQL UPSERT (INSERT ... ON CONFLICT UPDATE) fails Postgresql UPSERT 使用 ON CONFLICT 错误 - Postgresql UPSERT using ON CONFLICT Error 使用HugSQL通过ON CONFLICT DO UPDATE一次将多行插入PostgreSQL表中 - Using HugSQL to INSERT multiple rows at once into PostgreSQL table with ON CONFLICT DO UPDATE 如何在 postgresql 上使用 sqlalchemy 进行正确的 upsert? - How to do a proper upsert using sqlalchemy on postgresql? Postgresql:UPSERT / INSERT INTO 定义冲突 - Postgresql: UPSERT / INSERT INTO defining a conflict PostgreSQL 9.6 - 插入冲突后更新返回的地方 - PostgreSQL 9.6 - INSERT ON CONFLICT DO UPDATE WHERE RETURNING PostgreSQL INSERT ON CONFLICT UPDATE(upsert)使用所有排除的值 - PostgreSQL INSERT ON CONFLICT UPDATE (upsert) use all excluded values 具有唯一约束的 INSERT ON CONFLICT DO UPDATE SET(UPSERT)语句在同时运行时会产生约束冲突 - INSERT ON CONFLICT DO UPDATE SET (an UPSERT) statement with a unique constraint is generating constraint violations when run concurrently
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM