如何添加与 ON CONFLICT () DO UPDATE 的比较

How to add comparing to ON CONFLICT () DO UPDATE

我需要检查 table 中是否有当前用户今天的任何操作。 通常我是这样比较时间的:timestamp > CURRENT_TIMESTAMP::date

能否请您帮忙,如何在 INSERT in ON CONFLICT () DO UDPATE 中执行?

        INSERT INTO table (login, smth, timestamp)
          VALUES ('username', 'smth', CURRENT_TIMESTAMP)
        ON CONFLICT (login, timestamp) DO UPDATE
          SET smth = 'smth'
              timestamp = CURRENT_TIMESTAMP

这里将准确比较时间戳,但我需要检查一下,是否是今天,如上所示:timestamp > CURRENT_TIMESTAMP::date

谢谢!

如果您想存储时间戳但对日期有唯一约束,那么您可以在最新版本的 Postgres 中使用计算列轻松实现。这需要在 table:

中添加一个新的日期列
create table t (
     login text,
     smth text,
     ts timestamp,
     ts_date date generated always as (ts::date) stored
);

然后创建唯一约束:

create unique index unq_t_login_timestamp on t(login, ts_date);

现在您可以使用 on conflict:

INSERT INTO t (login, smth, ts)
    VALUES ('username', 'smth', CURRENT_TIMESTAMP)
    ON CONFLICT (login, ts_date) DO UPDATE
          SET smth = 'smth',
              ts = CURRENT_TIMESTAMP;

Here 是 db<>fiddle.

中的代码

编辑:

最好避开计算列,只使用:

create unique index unq_t_login_timestamp on t(login, (timestamp::date));

如果您可以使用 CTE,请参阅 here

如果你有问题,查询如下: (但是,我不清楚“timestamp > CURRENT_TIMESTAMP::date”是什么意思。)

with
"data"("w_login","w_smth","w_timestamp") as (
  select 'username2'::text, 'smth'::text, CURRENT_TIMESTAMP
),
"update" as (
  update "table" set ("smth","timestamp")=("w_smth","w_timestamp") from "data"
  where "login"="w_login" and "w_timestamp">CURRENT_TIMESTAMP::date
  returning *
)
insert into "table"
select * from "data"
where not exists (select * from "update");

DB Fiddle