sql组中最低的运行余额

我一直在努力解决这个问题,没有解决方案.

我希望在一组中获得最低的运行平衡.

这是一个示例数据

《sql组中最低的运行余额》

运行平衡是虚构的,不是表格的一部分.
运行余额也是动态计算的.

问题是我希望在特定月份(1月)获得最低的运行余额
因此,对于memberid 10001,输出应为150,对于memberid 10002,输出应为175,如图中突出显示的那样.
我希望的出局应该是

memberid |平衡

10001 | 150

10002 | 175

这可能只使用sql查询吗?

PS.使用c#计算最低运行平衡非常慢,因为我的表中有超过600,000条记录.

我已经更新了这个问题.

最佳答案 Mihir Shah提供的答案给了我如何解决我的问题的想法.

他的回答需要花费很多时间来处理,因为我的c#程序计算速度慢,因为他的代码在每条记录上循环.

这是我的答案,以获得具有运行值或运行总计的特定组(特定月份)中的最小最低值,而不会牺牲大量性能.

with IniMonth1 as 
(
select a.memberid, a.iniDeposit, a.iniWithdrawal, 
(cast(a.iniDeposit as decimal(10,2)) - cast(a.iniWithdrawal as decimal(10,2))) as RunningTotal
from
(
    select b.memberid, sum(b.depositamt) as iniDeposit, sum(b.withdrawalamt) as iniWithdrawal
    from savings b
    where trdate < '01/01/2016'
    group by b.memberid 
) a /*gets all the memberid, sum of deposit amount and withdrawal amt from the beginning of the savings before the specific month */
where cast(a.iniDeposit as decimal(10,2)) - cast(a.iniWithdrawal as decimal(10,2))  > 0 /*filters zero savings */
) 

《sql组中最低的运行余额》

,DetailMonth1 as 
(
select a.memberid, a.depositamt,a.withdrawalamt, 
(cast(a.depositamt as decimal(10,2)) - cast(a.withdrawalamt as decimal(10,2))) as totalBal, 
    Row_Number() Over(Partition By a.memberid Order By a.trdate Asc) RowID
from savings a
where
a.trdate >= '01/01/2016'
and 
a.trdate <= '01/31/2016'
and (a.depositamt<>0 or a.withdrawalamt<>0)
) /* gets all record within the specific month and gives a no of row as an id for the running value in the next procedure*/

《sql组中最低的运行余额》

,ComputedDetailMonth1 as 
(   
select a.memberid, min(a.runningbalance) as MinRunningBal
from
(
    select a.rowid, a.memberid, a.totalbal, 
    (
        sum(b.totalbal) + 
        (case 
        when c.runningtotal is null then 0
        else c.runningtotal
        end)
    )as runningbalance , c.runningtotal as oldbalance
    from DetailMonth1 a
    inner join DetailMonth1 b
        on  b.rowid<=a.rowid
        and a.memberid=b.memberid
    left join IniMonth1 c
    on a.memberid=c.memberid
    group by a.rowid,a.memberid,a.totalbal,c.runningtotal
) a

group by a.memberid
) /* the loop is only for the records of the specific month only making it much faster */  
/* this gets the running balance of specific month ONLY and ADD the sum total of IniMonth1 using join to get the running balance from the beginning of savings to the specific month */
/* I then get the minimum of the output using the min function*/

《sql组中最低的运行余额》
《sql组中最低的运行余额》

, OldBalanceWithNoNewSavingsMonth1 as
(
select a.memberid,a.RunningTotal
from 
IniMonth1 a
left join 
DetailMonth1 b
on a.memberid = b.memberid
where b.totalbal is null
)/*this gets all the savings that is not zero and has no transaction in the specific month making and this will become the default value as the lowest value if the member has no transaction in the specific month. */

《sql组中最低的运行余额》

,finalComputedMonth1 as
(
select a.memberid,a.runningTotal as MinRunTotal from OldBalanceWithNoNewSavingsMonth1 a
union 
select b.memberid,b.MinRunningBal from ComputedDetailMonth1 b
)/*the record with minimum running total with clients that has a transaction  in the specific month Unions with the members with no current transaction in the specific month*/

 select * from finalComputedMonth1 order by memberid /* display the final output */

《sql组中最低的运行余额》

我的储蓄表上有超过600k的储蓄记录

令人惊讶的是,此代码的性能非常高效.

使用我的c#程序花费近2小时来手动计算所有成员的每条记录.

此代码只需2秒,最多只需9秒即可计算所有内容.
我只是向c#显示另外2秒.

测试了此代码的输出,并使用我的c#程序与我的计算进行了比较.

点赞