在 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 有这样的输出,因为加法按以下方式工作
- 产品 AAAA 在购物车 1 和购物车 2 中,因此购物车 1 更新了商品 1 的数量 = 5
cart2 删除了 item3
- 商品 2 没有更改,因为购物车 2 中没有这样的商品
- cart1 中没有 product_id=CCCC 的商品,因此将 item4 的 cart_id 更改为 cart1
- 应删除购物车 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.
如果您想在同一语句中执行“更新插入”——并且 update
和 insert
——使用 `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.
我有如下购物车和商品 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 有这样的输出,因为加法按以下方式工作
- 产品 AAAA 在购物车 1 和购物车 2 中,因此购物车 1 更新了商品 1 的数量 = 5 cart2 删除了 item3
- 商品 2 没有更改,因为购物车 2 中没有这样的商品
- cart1 中没有 product_id=CCCC 的商品,因此将 item4 的 cart_id 更改为 cart1
- 应删除购物车 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.
如果您想在同一语句中执行“更新插入”——并且 update
和 insert
——使用 `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.