name|qty|
----+---+
A | 1|
A | 3|
A | 5|
A | 7|
A | 9|
现在销售了8种产品“A”,我们需要按以下顺序扣除库存:
name|qty| qty to be deducted|balance|
----+---+-------------------+-------+
A | 1| 1| 0|
A | 3| 3| 0|
A | 5| 4| 1|
A | 7| 0| 7|
A | 9| 0| 9|
第一步、用窗口函数计算产品A的累计数量:
select name,
qty,
sum(qty) over (partition by name order by qty) as c_qty
from ka
where name = 'A';
我们得到:(cqty为累计数量)
name|qty|cqty|
----+---+----+
A | 1| 1|
A | 3| 4|
A | 5| 9|
A | 7| 16|
A | 9| 25|
第二步,所以我们需要从前三行分配/扣除库存数量,但是有多少呢?我们来计算一下:
with cte_inv as (
select name,
qty,
sum(qty) over (partition by name order by qty) as cqty
from ka
where name = 'A')
select name,
qty,
cqty,
case when cqty < 8 then qty else qty - (cqty - 8) end as aqty
from cte_inv
where aqty >=0;
得到:(aqty为分配/扣除数量)
name|qty|cqty|aqty|
----+---+----+----+
A | 1| 1| 1|
A | 3| 4| 3|
A | 5| 9| 4|
with cte_inv as (
select rowid as pkey,
name,
qty,
sum(qty) over (partition by name order by qty) as cqty
from ka
where name = 'A'),
cte_ainv as (
select pkey,
name,
qty,
cqty,
case when cqty < 8 then qty else qty - (cqty - 8) end as aqty
from cte_inv
where aqty >=0)
update ka
set qty = qty - (select aqty from cte_ainv where pkey = ka.rowid)
where rowid <= (select max(pkey) from cte_ainv);
select * from ka;
结果:
name|qty|
----+---+
A | 0|
A | 0|
A | 1|
A | 7|
A | 9|
现在您可以看到清单已正确更新。 本练习中介绍了一些概念:
获取累计数量的窗口函数:sum() over (partition by name order by qty) as city
1条答案
按热度按时间u3r8eeie1#
假设业务规则是从最少数量中扣除库存,并且产品'A'的库存如下:
现在销售了8种产品“A”,我们需要按以下顺序扣除库存:
第一步、用窗口函数计算产品A的累计数量:
我们得到:(
cqty
为累计数量)第二步,所以我们需要从前三行分配/扣除库存数量,但是有多少呢?我们来计算一下:
得到:(
aqty
为分配/扣除数量)第三步现在我们知道(
aqty
)从产品'A'库存中扣除,我们可以更新该表。但是,在此之前,我们需要能够单独标识每一行。该表架构没有主键。我们可以做的是利用sqlite的rowid
功能,它是表中每一行的唯一标识符。在本例中,我们从产品库存表中进行选择:然后,我们得到以下结果:
好的,我们有一个唯一的键来标识每一行,我们可以继续并相应地更新表,方法是将上述查询作为CTE(Common Table Express)合并到一个查询中,如下所示:
结果:
现在您可以看到清单已正确更新。
本练习中介绍了一些概念:
sum() over (partition by name order by qty) as city
rowid
作为主键。建议:修改表架构以定义主键。在sqlite3中,我们可以使用
rowid
来解决设计问题。但是,这不是最佳实践。