lso*_*ira 3 sql sql-server sql-server-2008
我正在编写一个SQLServer 2008存储过程,它接受一个付款表,并尝试根据相关表中描述的一组规则(基本上是一组存储桶)分配这些付款.然而,分配(将支付价值放入桶中)正是导致我头痛的原因.
假设表Payments包含要支付的值和表Buckets是关于应该在每个桶中放入多少钱,直到要支付的初始值耗尽(达到0).
使用下面的表作为示例(实际用例有点做作,因为有一些复杂的标准来选择适合每次付款的存储桶):
PaymentId Value BucketId MaxAmount
-------------------------- --------------------------------
1 16.5 1 5.5
2 7.0 2 10
3 8.3
Run Code Online (Sandbox Code Playgroud)
对于付款1:5.5单位(该桶的最大值)应进入桶1,10个单位进入桶2(11.5是桶1的剩余量,但仍超过桶2的最大值)和1个单位(16.5 - 5.5 - 10) )应该放入桶3.重复所有付款.
这很容易在任何命令式语言中实现,甚至可能在带有for/while循环的SQL中实现,但我试图意识到是否有更好的方法(即使它是非可移植的并且特定于SQLServer 2005+).
我已经做了一些研究(主要是递归CTE),但没有真正想到的东西.我确信有很多StackOverflowers和SQL-fu一起回答它们的问题,所以我想把它放在那里看看......
非常感谢你的帮助.
将您的存储桶表放入临时表,然后有一个名为running total的额外列.这将有运行总计直到此连接,然后交叉加入付款和tempbucket表并指定支付<=运行totalin tempbucket表的条件.这应该可以解决您的问题.我已经使用Mafu Josh的DDL来创建以下查询,这要归功于他.我希望OP应该总是发布这些东西,以使其他人的生活更轻松.
看起来这个buckte表非常小.但是如果它是非常大的表.然后生成运行总计使用带变量的更新.这比下面的方法更有效.对我来说听起来这个表或多或少是静态的表,因此您可以将运行总计作为表本身的一部分.
DECLARE @Buckets TABLE (
BucketId INT,
MaxAmount DECIMAL(18,6)
)
INSERT INTO @Buckets VALUES (1, 5.5)
INSERT INTO @Buckets VALUES (2, 10)
INSERT INTO @Buckets VALUES (3, 8.3)
DECLARE @Payments TABLE (
PaymentId INT,
Value DECIMAL(18,6)
)
INSERT INTO @Payments VALUES (1,16.5)
INSERT INTO @Payments VALUES (2,7.0)
INSERT INTO @Payments VALUES (3,23.8)
DECLARE @tempBuckets TABLE (
BucketId INT,
MaxAmount DECIMAL(18,6) ,
currentruntotal decimal(18,6)
)
insert into @tempBuckets select bucketid,maxamount ,(select SUM(maxamount) from @Buckets bin where b.bucketid >=bin.bucketid)
--,isnull((select SUM(maxamount) from @Buckets bin where b.bucketid > bin.bucketid),0)
from @Buckets b
select * from @tempBuckets
select PaymentId,Value,BucketId,
case when p.Value >= tb.currentruntotal then tb.MaxAmount else p.Value - tb.currentruntotal + tb.MaxAmount end as bucketamount
from @Payments p inner join @tempBuckets tb on (p.Value >= tb.currentruntotal or p.Value between tb.currentruntotal - tb.MaxAmount and tb.currentruntotal )
order by PaymentId
go
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
980 次 |
| 最近记录: |