MYSQL INSERT或UPDATE IF

时间:2013-01-10 13:39:33

标签: mysql sql database

现在已经在网上浏览了一段时间,似乎无法遇到任何类似于我想要的东西。我知道这与我编写查询的方式有关,但任何帮助都会受到赞赏。

我想要做的基础是:

  • 如果某些项目不存在,请将其插入表格
  • 更新项目(如果项目确实存在)

它的格式为:

名称,条形码,项目,数量,位置,价格和日期

name - 可以在多行中使用 条形码 - 用于特定项目,但可以用作多个位置 item - 与条形码相同但包含名称 数量 - 自我解释 位置 - 这可以是不同的位置 价格 - 附加到特定商品 日期 - 上次购买该商品

棘手的是,“名称”可以在不同位置具有不同价格的多个项目(条形码和项目)。我们的想法是,客户可以看到他们在一定时间内购买了多少物品,因此他们知道他们需要多少钱来销售它。

然而,他们购买的价格可能会有所不同,因此如果价格与之前的购买价格不同,他们需要在表格中创建另一行。

整个事情背后的想法是,它记录每个位置的每个项目的“名称”有多少,然后记录他们在上次购买时购买的价格。

希望这是有道理的。

在伪代码中:

    Insert into table if does not exist
    - name, barcode, item, quantity, location, price and date
    If name, barcode, item, location and price are the same
    - Update quantity and date (if more recent)

3 个答案:

答案 0 :(得分:12)

首先,在名称,条形码,项目,位置和价格上添加UNIQUE约束。

ALTER TABLE  tableX
  ADD CONSTRAINT tableX_UQ
    UNIQUE (name, barcode, item, location, price) ;

然后您可以使用INSERT INTO ... ON DUPLICATE KEY UPDATE

INSERT INTO tableX
  (name, barcode, item, location, price, quantity, date)
VALUES
  (?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
  quantity = CASE WHEN VALUES(date) > date
               THEN quantity + VALUES(quantity)        -- add quantity
               ELSE quantity                           -- or leave as it is
             END
, date = CASE WHEN VALUES(date) > date
               THEN VALUES(date) ;                     -- set date to new date
               ELSE date                               -- or leave as it is
             END 

也可以使用

REPLACE,但行为存在差异(如果您有外键,这尤其重要)。有关详细信息,请参阅此问题“INSERT IGNORE” vs “INSERT … ON DUPLICATE KEY UPDATE”以及@Bill Kawin的答案,其中讨论了 INSERT IGNORE INSERT ... ON DUPLICATE KEY 和<之间的差异强> REPLACE

答案 1 :(得分:5)

您可以在mysql中使用replace语法。

但这只适用于......需要独特的字段的唯一索引。

所以你必须创建一个像这样的唯一索引:

alter <yourtable> add unique index(name, barcode, item, location, price);

然后您的插入/更新语法将变为

replace into <yourtable> (name, barcode, item, quantity, location, price, date)
 VALUES('name1', 'barcode1', 2, 'location1', 12.0, '25/12/2012');

修改

存储过程示例(简化和未经测试):

DELIMITER &&
DROP PROCEDURE IF EXISTS MyBase.UpdateOrInsert $$
CREATE PROCEDURE MyBase.UpdateOrInsert
(
  IN _name VARCHAR(10),
  IN _barcode VARCHAR(50),
  IN _quantity INTEGER
  IN _date DATE
)

DECLARE existingDate DATE default NULL;
BEGIN

SELECT date 
INTO existingDate
FROM <yourTable> where name = _name and barcode = _barcode;

if (existingDate IS NULL) then
   insert into <yourtable> (name, barcode, quantity, date) VALUES(_name, _barcode, _qantity, _date);
else
  if (existingDate < _date) then
     update <yourtable> 
     set quantity = _quantity,
       date = _date
     where name = _name
     and   barcode = _barcode;
  end if;
end if;
END &&

答案 2 :(得分:1)

感谢上述解决方案的所有帮助,我发现最终两者都非常接近。在下面找到它:

INSERT INTO `stock`
    (name, barcode, item, quantity, location, price, date)  
VALUES
    (?,?,?,?,?,?,?)                         
ON DUPLICATE KEY UPDATE
     quantity = CASE WHEN 
                VALUES(date) < $date
                THEN quantity + $quantity
                ELSE quantity 
                END,
    date = CASE WHEN 
                VALUES(date) < $date
                THEN VALUES(date)
                ELSE $date
                END