【问题标题】:SQL - IF EXISTS UPDATE ELSE INSERT [duplicate]SQL - IF EXISTS UPDATE ELSE INSERT [重复]
【发布时间】:2014-04-27 21:17:38
【问题描述】:

我有以下疑问:

INSERT INTO distance (deviceID,datum,tavolsag)
 SELECT 
deviceID, DATE(FROM_UNIXTIME(timestamp)) as datum, 
sum(case when distanceKM/1000<416 then distanceKM/1000 else 0 end) as tavolsag
FROM eventdata 
GROUP BY datum,deviceID;

我想知道当我每天运行查询/或使用“if exists update else insert”方法时如何避免数据重复。

谢谢

【问题讨论】:

    标签: mysql sql mysql-workbench


    【解决方案1】:

    如果您对 (deviceID, datum) 有 UNIQUE 约束,则可以使用 INSERT ... ON DUPLICATE KEY

    INSERT INTO distance (deviceID, datum, tavolsag)
    SELECT d.deviceID
         , DATE(FROM_UNIXTIME(d.timestamp)) as datum
         , SUM(CASE WHEN d.distanceKM/1000<416 
                    THEN d.distanceKM/1000
                    ELSE 0 END
           ) AS tavolsag 
      FROM eventdata d
     GROUP BY datum, deviceID
    ON DUPLICATE KEY
    UPDATE tavolsag = VALUES(tavolsag)
    

    当这个语句被执行时,这将尝试插入,如果插入违反了唯一键约束,而不是抛出错误,MySQL 将执行一个 UPDATE 代替,相当于:

    UPDATE distance
       SET tavolsag  = ?
     WHERE device_id = ?
       AND datum     = ?
    

    如果有多个唯一约束,则操作取决于将哪个唯一约束标记为违反。实际执行的更新将与引发错误的唯一约束相关。

    【讨论】:

    • 感谢您的解释! deviceId 和 datum 是唯一的约束。
    • @Peter:另一个注意事项:如果您的目标表定义了 AUTO_INCREMENT 列,那么即使在语句执行 UPDATE 操作时,运行 INSERT ... ON DUPLICATE KEY 语句也会消耗 auto_increment 值。 MySQL 首先尝试 INSERT(那是它使用 AUTO_INCREMENT 值的时候),然后仅在重复键异常时回退到 UPDATE。
    【解决方案2】:

    试试这个:

     INSERT INTO distance (deviceID,datum,tavolsag)
     SELECT deviceID,datum,tavolsag from(select 
    deviceID, DATE(FROM_UNIXTIME(timestamp)) as datum, 
    sum(case when distanceKM/1000<416 then distanceKM/1000 else 0 end) as tavolsag
    FROM eventdata 
    GROUP BY datum,deviceID)t
    on duplicate key update set datum=......, tavolsag = .....
    

    【讨论】:

      猜你喜欢
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 2012-09-08
      • 2013-11-26
      • 1970-01-01
      • 2017-09-09
      相关资源
      最近更新 更多