请问有人可以告诉我以下问题:我需要解决以下SQL查询。该数据库是Oracle 11g。
Select
article_cd, dc_cd,
nvl(soh_to_dmp - least(soh_to_dmp, nvl(sum(adj_alc_tot_frcst), 0)) ,0) v_dump_qty,
used_by_date
from
inventory
我附上了截图,以表格格式显示数据
please refer to this screenshot
我想要一个专栏" shirink"这给了" dump qty - sum(所有先前收缩)和如果dump qty - sum(所有先前收缩)< 0然后0如上图所示收缩为777 = 0表示0 =(0-777)= -777这应该为2548 = 0(2548 - 777)= 1771 = 8356 =(8356 - (777 + 1771))= 5808
我尝试使用滞后功能:
v_dump qty- lag ( v_dump qty) over ( partition by article_code,dc_code) order by ( article_code, dc code, used_date)
但它无效
答案 0 :(得分:0)
以下查询可能为解决您的问题提供了一个起点。我们现在没有很多测试数据。但是,当我们使用"库存"表,填写测试数据,如下所示:
create table inventory(
iid number primary key
, usebydate date
, qty number
);
-- select * from inventory
IID USEBYDATE QTY
1 30-AUG-2017 0
2 31-AUG-2017 0
3 30-SEP-2017 777
4 30-OCT-2017 0
5 01-NOV-2017 0
6 16-NOV-2017 0
7 30-NOV-2017 0
8 01-JAN-2018 0
9 31-JAN-2018 2548
10 28-FEB-2018 8356
...可以看出,包含自联接,结合CASE和"窗口"的查询可能会提供您需要的结果。
select
i.iid
, i.qty
, case
when ( i.qty - ( sum(i2.shrink) over ( order by i.iid rows between unbounded preceding and 1 preceding) ) ) < 0
or ( i.qty - ( sum(i2.shrink) over ( order by i.iid rows between unbounded preceding and 1 preceding) ) ) is null
then 0
else ( i.qty - ( sum(i2.shrink) over ( order by i.iid rows between unbounded preceding and 1 preceding) ) )
end shrink
from inventory i join
( select
iid
, case
when ( qty - ( sum(qty)
over ( order by iid rows between unbounded preceding and 1 preceding ) ) ) < 0 then 0
else ( qty - ( sum(qty)
over ( order by iid rows between unbounded preceding and 1 preceding) ) )
end shrink
from inventory
) i2
on i.iid = i2.iid
order by i.iid
;
输出:
IID QTY SHRINK
1 0 0
2 0 0
3 777 777
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 2548 1771
10 8356 5808
相同的查询,使用&#34; usebydate&#34;在ON子句中,给我们:
-- -----------------------------------------------------------------------------
-- on clause with date instead of iid
-- -----------------------------------------------------------------------------
select
i.usebydate
, i.qty
, case
when ( i.qty - ( sum(i2.shrink) over ( order by i.usebydate rows between unbounded preceding and 1 preceding) ) ) < 0
or ( i.qty - ( sum(i2.shrink) over ( order by i.usebydate rows between unbounded preceding and 1 preceding) ) ) is null
then 0
else ( i.qty - ( sum(i2.shrink) over ( order by i.usebydate rows between unbounded preceding and 1 preceding) ) )
end shrink
from inventory i join
( select
usebydate
, case
when ( qty - ( sum(qty)
over ( order by usebydate rows between unbounded preceding and 1 preceding ) ) ) < 0 then 0
else ( qty - ( sum(qty)
over ( order by usebydate rows between unbounded preceding and 1 preceding) ) )
end shrink
from inventory
) i2
on i.usebydate = i2.usebydate
order by i.usebydate
;
-- output
USEBYDATE QTY SHRINK
30-AUG-2017 0 0
31-AUG-2017 0 0
30-SEP-2017 777 777
30-OCT-2017 0 0
01-NOV-2017 0 0
16-NOV-2017 0 0
30-NOV-2017 0 0
01-JAN-2018 0 0
31-JAN-2018 2548 1771
28-FEB-2018 8356 5808
我确定可以修改/简化。此外,它还需要彻底的测试。适用于:Oracle 12c,Oracle 11g R2。 dbfiddle here