现在已经在网上浏览了一段时间,似乎无法遇到任何类似于我想要的东西。我知道这与我编写查询的方式有关,但任何帮助都会受到赞赏。
我想要做的基础是:
它的格式为:
名称,条形码,项目,数量,位置,价格和日期
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)
答案 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