在 table 中合并行

Combining rows within the table

我有如下购物车和商品 tables

Cart
+---------+-------------+
| cart_id | customer_id |
+---------+-------------+
|       1 |           1 |
|       2 |           2 |
+---------+-------------+

Item
+---------+---------+------------+------------+
| item_id | cart_id | product_id |   quantity |
+---------+---------+------------+------------+
|       1 |       1 | AAAA       |          7 |
|       2 |       1 | BBBB       |          2 |
|       3 |       2 | AAAA       |          5 |
|       4 |       2 | CCCC       |          3 |
+---------+---------+------------+------------+

我想编写查询,将一个购物车中的商品添加到另一个购物车中。 例如将 cart2 中的项目放入 cart1。这样查询后table的内容应该是这样的

Item
+---------+---------+------------+------------+
| item_id | cart_id | product_id | product_id |
+---------+---------+------------+------------+
|       1 |       1 | AAAA       |          5 |
|       2 |       1 | BBBB       |          2 |
|       4 |       1 | CCCC       |          3 |
+---------+---------+------------+------------+

Table 有这样的输出,因为加法按以下方式工作

  1. 产品 AAAA 在购物车 1 和购物车 2 中,因此购物车 1 更新了商品 1 的数量 = 5 cart2 删除了 item3
  2. 商品 2 没有更改,因为购物车 2 中没有这样的商品
  3. cart1 中没有 product_id=CCCC 的商品,因此将 item4 的 cart_id 更改为 cart1
  4. 应删除购物车 2,因为购物车 2 中的商品已合并到购物车 1 中

I want to write query which will add items in one cart into another cart. For example items in cart2 into cart1.

如果您想在同一语句中执行“更新插入”——并且 updateinsert——使用 `on conflict。

以唯一键开头:

alter table item unq_item_cart_product unique constraint (cart_id, product_id);

然后:

insert into item (cart_id, product_id, quantity)
     select 1, product_id, quantity
     from item
     where cart_id = 2
     on conflict (cart_id, product_id)
          do update set quantity = quantity + excluded.quantity;

虽然您的论点“我不需要插入新值...”可能是正确的,但@GordonLinoff 提供的插入过程比任何更新都容易得多 设计出来,因此可能更容易理解。然而,缺少的是从两个表中删除现已失效的购物车。可以处理级联 CTE(?) 或 SQL 函数。由于我不关心级联 DML CTE,因此我将提供一个函数。

create or replace function merge_carts(from_cart integer, to_cart integer)
  returns void
  language sql 
as $$
   insert into item(cart_id,product_id,quantity)
     select to_cart, product_id, quantity
       from item   
      where cart_id = from_cart
         on conflict (cart_id,product_id)
         do update set quantity = excluded.quantity; 
   delete 
     from item
    where cart_id = from_cart; 
   delete 
     from cart
    where cart_id = from_cart;            
$$;

现在,一旦我知道涉及的 cart_ids,我就调用 Merge_Carts 函数。

关键问题是您非常确定标识​​为客户 2 的“匿名用户”实际上是客户 1。
查看完整案例 here.