MySQL - 更新连接&增量

时间:2013-12-16 23:29:53

标签: mysql sql sql-update

请参阅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操作的理解存在漏洞。谢谢你的帮助。

2 个答案:

答案 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列中checkoutid的{​​{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

SqlFiddle Demo