MySql -在更新时避免重复记录


MySql - Avoid duplicate records on update

我有以下更新查询,当用户登录到他们的帐户,并在他们的购物车中放置项目之前登录(在表上设置的临时帐户)运行…

UPDATE cart_items SET account_id=$account WHERE account_id=$cookieId;

这偶尔会产生重复的结果,看起来像这样:

id | account_id | itemNumber | itemQuantity
------------------------------------------
20 | 10         | 6          | 2
25 | 10         | 6          | 1

我想做的是写一个查询,避免创建这些重复的记录,只留下这样的单个记录:

id | account_id | itemNumber | itemQuantity
------------------------------------------
20 | 10         | 6          | 3

我认为使用DUPLICATE KEY UPDATE可能是我正在寻找的,但我不能得到我的头在它周围。有人能帮我一下吗?

|| Updated |

让我们假设您有一个临时id为15的未登录用户,他订购了2件物品,itemNumber为6:

id | account_id | itemNumber | itemQuantity
------------------------------------------
20 | 15         | 6          | 2

临时id存储在变量$cookieId中,值为15。现在让我们假设这个用户登录到他的帐户,id存储在$account中,值为10。

作为登录过程的一部分,您希望执行您的查询:

UPDATE cart_items SET account_id=$account WHERE account_id=$cookieId;

(尽管准备好的语句应该是您想要查看的内容)。

条目现在看起来应该是这样的:

id | account_id | itemNumber | itemQuantity
------------------------------------------
20 | 10         | 6          | 2

现在让我们假设用户10想再买1件物品6,那么最合理的做法是

SELECT * FROM cart_items WHERE account_id = $account AND itemNumber = $itemNumber; // $itemNumber is 6

如果查询返回true,则

UPDATE cart_items SET itemQuantity = itemQuantity+$numerOfItemsInOrder WHERE $account = $account AND itemNumber = $itemNumber; // $itemNumber is 6

,否则插入

您肯定不希望在用户注销时更新account_id,只希望在用户登录时更新。

好的,这就是我所做的…这可能有点冗长,但它工作…

UPDATE cart_items SET account_id=$account WHERE account_id=$cookieId;
UPDATE cart_items t
  JOIN (
    SELECT MinID, b.itemQuantity LatestName
    FROM cart_items b
    JOIN (
      SELECT MIN(id) MinID, MAX(id) MaxID
      FROM cart_items
      GROUP BY account_id, itemNumber
      HAVING COUNT(*) > 1
    ) g ON b.id = g.MaxID
  ) rs ON t.id = rs.MinID
SET t.itemQuantity = t.itemQuantity+LatestName;
DELETE `cart_items` 
FROM `cart_items`
LEFT OUTER JOIN (
   SELECT MIN(`id`) as `id`, `account_id`, `itemNumber`
   FROM `cart_items` 
   GROUP BY `account_id`, `itemNumber`
) as `KeepRows` ON
   `cart_items`.`id` = `KeepRows`.`id`
WHERE
   `KeepRows`.`id` IS NULL