请参阅this sqlfiddle(以下也应该提到小提琴)。目标是将所有签出的项目返回到项目表,更新数量值。
CREATE TABLE checkout(
id INT NOT NULL
-- toUser, indexes, etc
);
CREATE TABLE inventory(
id INT NOT NULL AUTO_INCREMENT,
quantity INT DEFAULT 0,
PRIMARY KEY (id)
);
INSERT INTO inventory(quantity) VALUES(90);
INSERT INTO inventory(quantity) VALUES(42);
-- 10 values
INSERT INTO checkout(id) VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
-- 8 values
INSERT INTO checkout(id) VALUES(2),(2),(2),(2),(2),(2),(2),(2);
-- Return all the checked out items back to the inventory (up the quantity)
UPDATE inventory i
INNER JOIN checkout c ON c.id = i.id
SET i.quantity = i.quantity + 1;
在此更新之后,我期待这个结果:
Inventory:
id = 1, quantity = 100
id = 2, quantity = 50
相反,收到了:
Inventory:
id = 1, quantity = 91
id = 2, quantity = 43
联接返回18行:
SELECT * FROM inventory i INNER JOIN checkout c ON c.id = i.id;
我相信我对UPDATE操作的理解存在漏洞。谢谢你的帮助。
答案 0 :(得分:2)
正如UPDATE
Syntax所述:
对于多表更新,无法保证以任何特定顺序执行分配。
换句话说,由于inventory
表中的每条记录多次连接到checkout
表,因此无法保证右侧的i.quantity
值任务将反映以前的更新。
作为@newfurniturey suggests,您可以从相关的UPDATE
子查询中找到COUNT()
。但是,我更倾向于在这里定义triggers:
CREATE TRIGGER checkout_ins AFTER INSERT ON checkout FOR EACH ROW
UPDATE inventory SET quantity = quantity + 1 WHERE id = NEW.id;
CREATE TRIGGER checkout_upd AFTER UPDATE ON checkout FOR EACH ROW
UPDATE inventory SET quantity = quantity + CASE id
WHEN OLD.id THEN -1
WHEN NEW.id THEN +1
END WHERE id IN (OLD.id, NEW.id);
CREATE TRIGGER checkout_del AFTER DELETE ON checkout FOR EACH ROW
UPDATE inventory SET quantity = quantity - 1 WHERE id = OLD.id;
答案 1 :(得分:1)
如果我了解您的目标,您希望为1
列中quantity
列中checkout
列id
的{{1}}添加checkout
?例如,如果id = 1
的{{1}}中有10个条目,则您将quantity = quantity + 10
...
如果是这种情况,您需要在group by
声明中使用UPDATE
函数(而不是JOIN
);您可以使用子查询和COUNT()
:
UPDATE inventory i
SET i.quantity = i.quantity + (
SELECT COUNT(c.id) FROM checkout c WHERE c.id = i.id
);
结果:
SELECT * FROM inventory;
ID QUANTITY
1 100
2 50