SQL IF 存在日期按天做增量更新否则插入数据

Posted

技术标签:

【中文标题】SQL IF 存在日期按天做增量更新否则插入数据【英文标题】:SQL IF exist date by day do increment update else insert data 【发布时间】:2018-06-02 07:22:49 【问题描述】:

如何将以下语句表示为 SQL 查询?

IF EXISTS (SELECT * FROM expense_history 
           WHERE user_id = 40 
             AND DATE_FORMAT(expense_history.created_date , '%Y-%m-%d') = '2018-06-02' 
             AND camp_id='80') 
    UPDATE expense_history  
    SET clicks = clicks + 1, 
        amount = amount + 1 
    WHERE user_id = 40 
      AND DATE_FORMAT(expense_history.created_date, '%Y-%m-%d') = '2018-06-02' 
      AND camp_id = '80'
ELSE
   INSERT INTO expense_history (camp_id, created_date, amount, user_id) 
   VALUES ('80', '2018-06-02 12:12:12', '1', '40')
END IF;

如果按天设置,我只想增加点击次数和数量,否则我想添加新行。

【问题讨论】:

Solutions for INSERT OR UPDATE on SQL Server的可能重复 搜索 UPSERT 这是在 mysql 上吗? SQL 中没有IF - 您使用的是哪个 DBMS 产品? 什么版本的 MySQL? 【参考方案1】:

这在 MySQL 中非常棘手。您正在存储 datetime,但您希望日期部分是唯一的。

从 MySQL 5.7.? 开始,您可以将计算列用于唯一约束。这是一个例子:

create table expense_history (
  user_id int,
  camp_id int,
  amount int default 0,
  clicks int default 1,
  . . .
  created_datetime datetime,  -- note I changed the name
  created_date date generated always as (date(created_datetime)),
  unique (user_id, camp_id, created_datetime)
);

然后你可以做这样的工作:

INSERT INTO expense_history (camp_id, created_datetime, amount, user_id) 
    VALUES (80, '2018-06-02 12:12:12', 1, 40)
    ON DUPLICATE KEY UPDATE
        amount = COALESCE(amount + 1, 1),
        clicks = COALESCE(clicks + 1, 1);

早期版本的 MySQL 不支持生成列。它们也不支持unique 上的功能。但是你可以在 varchar 的前缀索引上使用技巧来做你想做的事:

create table expense_history (
  user_id int,
  camp_id int,
  amount int default 0,
  clicks int default 1,
  . . .
  created_datetime varchar(19), 
  unique (created_datetime(10))
);

这具有相同的效果。

另一种选择是将日期和时间存储在单独的列中。

【讨论】:

【参考方案2】:

我假设您的数据库是 mysql,因为 DATE_FORMAT() 函数(并编辑了您的问题)。

那么,通过下面这样的机制,你就可以为所欲为,

如果 camp_id、amount、user_id 列有一个 COMPOSITE PRIMARY KEY

SET @camp_id = 80,
    @amount  =  1,
    @user_id = 40,
    @created_date = sysdate();

INSERT INTO expense_history(camp_id,created_date,amount,user_id,clicks)
VALUES(@camp_id,@created_date,@amount,@user_id,ifnull(clicks,1))
ON DUPLICATE KEY UPDATE 
    amount = @amount + 1,
    clicks = ifnull(clicks,0)+1;

SQL Fiddle Demo

【讨论】:

以上是关于SQL IF 存在日期按天做增量更新否则插入数据的主要内容,如果未能解决你的问题,请参考以下文章

DB2 - 如果日期 X 的表为空,则插入,否则继续

如果存在,我需要更新,否则使用 Linq 插入 SQL

SQL Server CE:如果存在更新,否则插入

如何在 PL/SQL 中增量集成数据

SQL 查询 - 如果存在则更新,否则插入

SQL Select:如果存在则更新,如果不存在则插入 - 使用日期部分比较?