按 somecolumn 分组以获得总值并按 somecolumn 以相反的顺序对值求和
Posted
技术标签:
【中文标题】按 somecolumn 分组以获得总值并按 somecolumn 以相反的顺序对值求和【英文标题】:group by somecolumn to get total value and sum the value in reverse order by somecolumn 【发布时间】:2019-05-29 02:32:49 【问题描述】:表格&DDL:
|id |gooditem|amt |
|---|--------|-----|
|1 |apple |1000 |
|2 |apple |2000 |
|3 |apple |-3000|
|4 |apple |500 |
|5 |apple |1500 |
|6 |pen |1000 |
|7 |pen |2000 |
|8 |pen |-3000|
|9 |pen |500 |
|10 |pen |2500 |
CREATE TABLE T
([id] int, [gooditem] varchar(5), [amt] int)
;
INSERT INTO T
([id], [gooditem], [amt])
VALUES
(1, 'apple', 1000),
(2, 'apple', 2000),
(3, 'apple', -3000),
(4, 'apple', 500),
(5, 'apple', 1500),
(6, 'pen', 1000),
(7, 'pen', 2000),
(8, 'pen', -3000),
(9, 'pen', 500),
(10, 'pen', 2500)
;
Test Demo Link
逻辑
产品foo总量为2000,pen为3000 按ID逆序求和预期结果
|id |gooditem|amt |formula |total_amt|
|---|--------|-----|-----------------------------|---------|
|1 |foo |1000 |2000-1500-500--3000-2000-1000|0 |
|2 |foo |2000 |2000-1500-500--3000-2000 |1000 |
|3 |foo |-3000|2000-1500-500--3000 |3000 |
|4 |foo |500 |2000-1500-500 |0 |
|5 |foo |1500 |2000-1500 |500 |
|6 |pen |1000 |3000-1500-500--3000-2000-1000|0 |
|7 |pen |2000 |3000-1500-500--3000-2000 |1000 |
|8 |pen |-3000|3000-1500-500--3000 |2000 |
|9 |pen |500 |3000-1500-500 |1000 |
|10 |pen |1500 |3000-1500 |1500 |
我的尝试和问题
我尝试使用rownumber()
来订购 id 并使用 id 总和数据。
但是我在gooditem to get total value and sum the value in reverse order by somecolumn
的组上有问题
版本
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
我对 sql server 2008 的回答
with cte as (
select row_number() over (partition by [gooditem] order by id desc) rnk
,sum(T1.amt) over (partition by T1.gooditem) total_amt,*
from T T1
)
,cte2 as (
select T1.gooditem ,T1.id,T1.rnk,T1.amt ,T1.total_amt -T1.amt as total_amt from cte T1
where T1.rnk = 1
union all
select T1.gooditem ,T1.id,T1.rnk,T1.amt ,T2.total_amt - T1.amt as total_amt from cte T1
inner join cte2 T2 on T1.[gooditem] = T2.[gooditem] and T1.rnk = T2.rnk+1
)
select T1.id,T1.gooditem,T1.amt ,T1.total_amt
from cte2 T1
order by id
db<>fiddle
【问题讨论】:
【参考方案1】:你正在寻找一个累计和:
select id, gooditem, amt,
(2000 - sum(amt) over (partition by gooditem order by id desc)) as total_amt
from t
order by id;
Here 是一个 dbfiddle。
编辑:
如果您需要总数,您也可以使用窗口函数来计算:
select id, gooditem, amt,
(sum(amt) over (partition by gooditem) -
sum(amt) over (partition by gooditem order by id desc)
) as total_amt
from t
order by id;
db<>fiddle 非常相似。
【讨论】:
谢谢,但是不能使用常量2000,这是我之前试过的问题点 @ITWeiHan 。 . .那只需要累积总和。以上是关于按 somecolumn 分组以获得总值并按 somecolumn 以相反的顺序对值求和的主要内容,如果未能解决你的问题,请参考以下文章