Tsql T-SQL将一个数值拆分为多个帐户的优雅解决方案
我有一个问题,我相信有一个完美的解决方案,但希望得到一些帮助 所以我有一张人员表和一个数值。除此之外,还有一个表,其中包含将每个人的值划分为多个帐户的规则,规则可以是最大值或值的百分比 这是这些表的简化版本Tsql T-SQL将一个数值拆分为多个帐户的优雅解决方案,tsql,division,Tsql,Division,我有一个问题,我相信有一个完美的解决方案,但希望得到一些帮助 所以我有一张人员表和一个数值。除此之外,还有一个表,其中包含将每个人的值划分为多个帐户的规则,规则可以是最大值或值的百分比 这是这些表的简化版本 Persons(PersonID int, Value decimal) Account(AccountID int, PersonID int) Distribution(AccountID int, MaxValue decimal Null, Percentage decimal
Persons(PersonID int, Value decimal)
Account(AccountID int, PersonID int)
Distribution(AccountID int, MaxValue decimal Null, Percentage decimal null)
在某个时刻,我需要将这些数值划分到第三个表中——该表包含帐户和被划分到该帐户的值
AccountValues(AccountID int, AccountValue decimal)
每个人的账户数量不是固定的。在分布表中-如果两个分布值都为null-所有剩余值都将进入该帐户。
分配的顺序是根据他们的ID
数据可能是这样的
Persons table
PersonID Value
1 1000,00
2 2000,00
3 5000,00
4 500,00
Accounts table
AccountID PersonID
1 1
2 1
3 2
4 2
5 2
6 3
7 3
8 4
9 4
10 4
Distribution table
AccountID MaxValue Percentage
1 500,00 null
2 null null
3 null 0,5
4 null 0,2
5 null null
6 1000,00 null
7 null null
8 2000,00 null
9 null 0,2
10 null null
对于T-SQL来说还是有点陌生,所以需要帮助找到最简单、最高效的解决方案
所以现在我在考虑3种可能的解决方案。
1.最少优雅-计算每个人的最大帐户数,并多次循环。
2.光标-也许是最好的方式?
3.关于CTE递归,我一无所知我使用了一个CTE。也许有一种更聪明的方法来计算总数,但我认为这是可行的 数据设置:
declare @Persons table (PersonID int not null,Value decimal(18,4) not null)
insert into @Persons(PersonID,Value) values
(1,1000.00),
(2,2000.00),
(3,5000.00),
(4,500.00)
declare @Accounts table (AccountID int not null,PersonID int not null)
insert into @Accounts(AccountID,PersonID) values
(1,1),
(2,1),
(3,2),
(4,2),
(5,2),
(6,3),
(7,3),
(8,4),
(9,4),
(10,4)
declare @Distribution table (AccountID int not null,MaxValue decimal(18,4) null,Percentage decimal(6,5) null)
insert into @Distribution (AccountID,MaxValue,Percentage) values
(1,500.00,null),
(2,null,null),
(3,null,0.5),
(4,null,0.2),
(5,null,null),
(6,1000.00,null),
(7,null,null),
(8,2000.00,null),
(9,null,0.2),
(10,null,null)
declare @AccountValues table (AccountID int not null,Value decimal(18,4) null)
实际查询:
;With DisbValues as (
select
a.AccountID,
p.PersonID,
CASE
WHEN d.MaxValue is not null then d.MaxValue
WHEN d.Percentage is not null then d.Percentage * p.Value
END as Value,
p.Value as TotalAvailable
from
@Distribution d
inner join
@Accounts a
on
d.AccountID = a.AccountID
inner join
@Persons p
on
a.PersonID = p.PersonID
), CumulativeValues as (
select
AccountID,
PersonID,
Value,
COALESCE((select SUM(Value) from DisbValues d2 where d2.PersonID = d.PersonID and d2.AccountID < d.AccountID),0) as PrevValue,
TotalAvailable
from
DisbValues d
)
insert into @AccountValues (AccountID,Value)
select
AccountID,
CASE WHEN PrevValue < TotalAvailable THEN
CASE WHEN PrevValue + Value < TotalAvailable THEN Value --Entirely satisfied
ELSE TotalAvailable - PrevValue --Partially satisfied
END
ELSE
0 --Not satisfied
END
from CumulativeValues
第一个CTE值消除了从百分比角度考虑的需要。我假设我们使用的是可用总价值的百分比,而不是试图满足特定帐户时剩余的百分比。然后,第二个CTE累积值将早期账户需要填写的所有值相加
然后,在最后一个查询中,我们可以将事情分解为3种情况,如注释所示。游标几乎从来都不是最好的解决方案其他一个或两个表中是否缺少PersonID?我不太明白你的叙述。如果您可以添加5到10行之间的样本数据,显示一些变化和预期结果,我可以试一试。@user1659425-没问题。它只有一个问题——我刚刚回来看它,我自己也不知道它是如何处理空值的。一旦我自己解决了这个问题,我可能会添加一个解释