如何在计数器表中增加值

时间:2019-04-29 18:40:30

标签: postgresql

在我的桌子上,我有以下方案:

id - integer | date - text | name - text | count - integer

我只想计算一些动作。

我想在date = '30-04-2019'还不存在的时候放1。 我想在行已经存在时放+1。

我的想法是:

UPDATE "call" SET count = (1 + (SELECT count 
                                FROM "call" 
                                WHERE date = '30-04-2019')) 
WHERE date = '30-04-2019' 

但是当行不存在时,它将无法正常工作。

有可能没有一些额外的触发器,等等...

1 个答案:

答案 0 :(得分:0)

您可以使用writeable CTE来实现。另外,可以将UPDATE语句简化为简单的set count = count + 1,而无需进行子选择。

with updated as (
  update "call" 
     set count = count + 1
  where date = '30-04-2019'
  returning id
)
insert into "call" (date, count)
select '30-04-2019', 1
where not exists (select *
                  form updated);

如果更新未找到行,则where not exists条件为true,并且将执行insert

请注意,对于从多个事务中并发执行上述操作,是不安全的。如果要确保安全,请在unique列上创建一个date索引。然后改用INSERT ... ON CONFLICT

insert into "call" (date, count)
values ('30-04-2019', 1)
on conflict (date) 
do update 
   set count = "call".count + 1;

再次:以上要求在date列上使用唯一索引(或约束)。


与眼前的问题无关,但是:将日期存储在text列中是真的,这确实是个坏主意。您应该更改表定义,并将"date"列的数据类型更改为date