sql-server 有条件地将列的值求和为定义的值[已关闭]

owfi6suc  于 2022-10-31  发布在  其他
关注(0)|答案(1)|浏览(115)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题吗?**通过editing this post添加详细信息并阐明问题。

6天前关闭。
Improve this question
我有这样一张表:

id | name | amount (in $)
--------------
1  |  A   | 10
1  |  A   | 5 
1  |  A   | 20
1  |  A   | 20
1  |  A   | 40
1  |  A   | 30
2  |  B   | 25
2  |  B   | 20
2  |  B   | 30
2  |  B   | 30

我如何对$5以上的每个ID的amount列求和,以便当求和达到某个值(例如$50)时,它在下一行中对该ID执行另一个求和?
因此,根据上表,我们将得到:

id | name | amount (in $)
--------------
1  |  A   | 5 --skips the amount that is not above $5
1  |  A   | 50 --the next three rows sum up to $50
1  |  A   | 70 --the value of the next row is not up to $50, so it sums the next line. Summation is more than $50, but no problem
2  |  B   | 75
2  |  B   | 30
jdgnovmf

jdgnovmf1#

这可能不是最简单的解决方案,但它确实有效。
您的示例数据存在根本性的缺陷,因为您需要一个列来对行进行排序,以实现您想要的结果。我已经假定您通过向示例数据添加一个identify列来获得这样一个列。
帮助理解的要点:

  1. 5排或更少的单独处理;因此标识该行以便稍后显示它,并将其从运行总计中筛选出来。
    1.计算一个标识的运行合计,忽略太小的金额。
    1.当超过指定的阈值时,使用此运行总数计算(除以阈值)
    1.用于保留阈值发生更改的每一行的标志,即阈值被超过一次、两次、三次等。
    1.对于保留的每一行,减去前一个值以给予差值。
declare @MyTable table (id int, [name] char(1), amount money, uniqueid int identity (1,1));

insert into @MyTable (id, [name], amount)
values
(1,'A',10),
(1,'A',5),
(1,'A',20),
(1,'A',20),
(1,'A',40),
(1,'A',30),
(2,'B',25),
(2,'B',20),
(2,'B',30),
(2,'B',30);

declare @LowerAmount money = 5, @CutoffAmount money = 50;

with cte1 as (
    select *
        , sum(case when amount > @LowerAmount then amount else 0 end) over (partition by id order by uniqueid asc) RunningTotal
        , round(sum(case when amount > @LowerAmount then amount else 0 end) over (partition by id order by uniqueid asc) / @CutoffAmount, 0, 1) CutoffTest
        , case when amount <= @LowerAmount then 1 else 0 end TooSmall
    from @MyTable
), cte2 as (
    select *
        , case when CutoffTest <> lag(CutoffTest, 1, 0) over (partition by id order by uniqueid asc) then RunningTotal else null end RowToKeep
    from cte1
)
select id, [name]
    , case when TooSmall = 1 then amount else RowToKeep-coalesce(lag(RowToKeep,1,0) over (partition by id order by uniqueid asc),0) end amount
from cte2
where TooSmall = 1 or RowToKeep is not null
order by uniqueid asc;

按要求退货:
| 标识符|姓名|数量|
| - -|- -|- -|
| 一个|A级|五点整|
| 一个|A级|50元|
| 一个|A级|七十元|
| 2个|B|七十五元|
| 2个|B| 30点整|
注意:提供DDL+DML(如我在这里所示)会使问题更容易回答。

相关问题