Create Table #Invoices
(
InvoiceID int,
Amount money,
ProjectID int
)
insert into #Invoices
(
InvoiceID,
Amount,
ProjectID
)
select
1,
100,
1
union all
select
2,
100,
2
union all
select
3,
100,
3
union all
select
4,
100,
4
Create Table #Projects
(
ProjectID int,
AccountCode int
)
insert into #Projects
(
ProjectID,
AccountCode
)
select
1,
'12345'
union all
select
2,
'12345'
union all
select
2,
'7890'
union all
select
3,
'800'
union all
select
3,
'234'
union all
select
3,
'987'
union all
select
4,
'800'
union all
select
4,
'234'
union all
select
4,
'987'
union all
select
4,
'2579'
这是几年前这个问题的后续问题 将 1 行分成 2 行,占总数的百分比
我有上面的示例数据,我想做的是拆分发票行 根据 AccountCode 分成多行,但计算分割,所以如果有 2个相关AccountCodes,金额应分割50%/50%,如果有3个,则分割 33.3%/33.3%/33.3%,但一行是 34,所以它与总数持平。等等等等。
这是我到目前为止整理的一个查询:
select
I.*,
P.AccountCode,
I.Amount / count(I.InvoiceID) over (partition by P.ProjectID) as SplitAmount
from
#Invoices I
Inner Join #Projects P on
I.ProjectID = P.ProjectID
order by
I.InvoiceID
它似乎在 SplitAmount 方面有效,但有一个问题。发票ID 3 包含三个值 33.33,等于 99.99。我怎样才能确保分裂会 无论分割次数如何,总金额始终等于?
这是一张显示我想要的最终结果的表格。我已将其中一行更改为 33.34 所以我得到了 100 结果,但请记住,该金额可以是任何金额。
发票ID | 金额 | 项目ID | 账号代码 | 分割金额 |
---|---|---|---|---|
1 | 100.00 | 1 | 12345 | 100.00 |
2 | 100.00 | 2 | 12345 | 50.00 |
2 | 100.00 | 2 | 7890 | 50.00 |
3 | 100.00 | 3 | 800 | 33.33 |
3 | 100.00 | 3 | 234 | 33.33 |
3 | 100.00 | 3 | 987 | 33.34 |
4 | 100.00 | 4 | 800 | 25.00 |
4 | 100.00 | 4 | 234 | 25.00 |
4 | 100.00 | 4 | 987 | 25.00 |
4 | 100.00 | 4 | 2579 | 25.00 |
总结
SplitAmount
并用 #Invoices.Amount
进行验证,并将任何差异调整到其中一行。
在计算
round()
时,您可能需要
SplitAmount
保留 2 位小数
select *,
SplitAmount
+ case when rn = 1
then i.Amount - sum (i.SplitAmount)
over (partition by i.ProjectID)
else 0
end as AdjustedSplitAmount
from
(
select
I.*,
P.AccountCode,
round(I.Amount / count(I.InvoiceID) over (partition by P.ProjectID), 2) as SplitAmount,
row_number() over (partition by P.ProjectID order by p.AccountCode) as rn
from
#Invoices I
Inner Join #Projects P on
I.ProjectID = P.ProjectID
) i