假设以下一个表,有A这么一个物品,单价(UNIT_PRICE)的基准是100,SELL_NUM是这个物品的销售数量,假设A这个物品在一组ID内最多只能销售出三个,且销售第一个时候,可以以基准价格100来售卖,但在售出第二个和第三个时候价格只允许是上一个的60%,即1000.6、1000.6*0.6,超出的数量需乘上单价,作违规金额填入EXCEED_AMOUNT这一列里面,其中,如果第一到第三个中超出基准定价标准的金额部分也需要乘上相应的数量填入EXCEED_AMOUNT这一列里面,我个人思路是用ROWNUMBER OVER、SUM OVER和CASE WHEN条件判断函数来达到目的,但在处理CASE WHEN函数的时候,就蒙圈了,个人写的代码如下,请教各位怎样能进一步去编写这个代码
WITH A AS
(SELECT M.*,
SUM(M.NUM) OVER(PARTITION BY M.ID ORDER BY M.UNIT_PRICE DESC, M.GN) SN
FROM (SELECT T2.ID,
T2.UNIT_PRICE,
sum(T2.SELL_NUM) NUM,
ROW_NUMBER() OVER(PARTITION BY T2.ID ORDER BY T2.UNIT_PRICE DESC) GN
FROM TEST_TABLE T2
GROUP BY T2.ID, T2.UNIT_PRICE) M)
SELECT A.ID,
A.ITEM,
A.UNIT_PRICE,
A.SELL_NUM,
(CASE WHEN
ELSE
END) EXCEED_AMOUNT
FROM A
按你这个思路,会涉及到一个分摊问题,把问题搞复杂了,因为你这个表里面没有唯一键,无法排序,不能确定哪一行发生在前哪一行发生在后;就算有个时间排序,假设第三行和第四行数据一样,都可以作为临界线,这样随便挑一行出来都能作为超标,那样强行按顺序分摊没有任何意义。
这个题的最终目的,应该只是想揪出哪些id有违规,并且算出他总计应该支付多少、总计实际支付了多少、以及购买数量,这样也可以得出他总计违规了多少金额,至于要查明细,得到违规的id后再去查原表就是了。
给你一个简单易懂的sql
---模拟数据
create table test_20210119_13
(id number,
item varchar2(200),
unit_price number,
sell_num number);
insert into test_20210119_13 VALUES (1,'A',100,2);
insert into test_20210119_13 VALUES (1,'A',60,1);
insert into test_20210119_13 VALUES (1,'A',40,3);
insert into test_20210119_13 VALUES (1,'A',40,1);
----查询sql
select ID,
ITEM,
SUM(UNIT_PRICE * SELL_NUM) 实付总计,
SUM(SELL_NUM) 数量总计,
CASE
WHEN SUM(SELL_NUM) = 1 THEN
100
WHEN SUM(SELL_NUM) = 2 THEN
100 + 100 * 0.6
WHEN SUM(SELL_NUM) = 3 THEN
100 + 100 * 0.6 + 100 * 0.6 * 0.6
WHEN SUM(SELL_NUM) > 3 THEN
100 + 100 * 0.6 + 100 * 0.6 * 0.6 + (SUM(SELL_NUM) - 3) * 100
END 应付总计
from test_20210119_13
GROUP BY ID, ITEM