1

我有一个我认为有一个完美优雅的解决方案的问题,但需要一些帮助。

所以我有一张人员表和一个数值。除此之外,还有一个表格,其中包含该值(每人)到多个帐户的划分规则,规则可以是最大值或值的百分比。

这是这些表格的简化版本。

Persons(PersonID int, Value decimal)

Account(AccountID int, PersonID int)

Distribution(AccountID int, MaxValue decimal Null, Percentage decimal null)

在某些时候,我需要将这些数值划分到第三个表中 - 该表保存了帐户和该帐户的值。

AccountValues(AccountID int, AccountValue decimal)

账户数量(每人)不固定。在分布表中 - 如果两个分布值都为空 - 所有剩余值都将转到该帐户。分发顺序是按他们的 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递归(我对此一无所知)

4

1 回答 1

0

我用过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 DisbValues(然后,第二个 CTE ( CumulativeValues) 将早期帐户需要填写的所有值相加。

然后,我们可以在最终查询中将事情分解为 3 种情况,如注释所示。

于 2012-09-10T08:52:12.737 回答