从小到大扣除金额,直到金额用完
To deduct amount starting with the smallest until amount is exhausted
我有一个 SQL table 看起来像这样
CREATE TABLE #Temp_Supply
(
Supplier_Name Varchar(30),
Invoice_Number Varchar(20),
Amount Money
)
INSERT INTO #Temp_Supply (Supplier_Name, Invoice_Number, Amount)
SELECT 'Supply1', 'Inv1', 1000 UNION
SELECT 'Supply1', 'Inv2', 2000 UNION
SELECT 'Supply1', 'Inv3', 3000 UNION
SELECT 'Supply2', 'Inv1', 1500 UNION
SELECT 'Supply2', 'Inv2', 2500
CREATE TABLE #Temp_Supply_Deduction
(
Supplier_Name Varchar(30),
Deduction_Amount Money
)
INSERT INTO #Temp_Supply_Deduction(Supplier_Name, Deduction_Amount)
SELECT 'Supply1', 2500 UNION
SELECT 'Supply2', 500
SELECT * FROM #Temp_Supply
SELECT * FROM #Temp_Supply_Deduction
在选择供应时table从最小的发票编号开始扣除保留金额,直到金额用完
例外的输出应该是
Supplier_Name
Invoice_Number
Amount
Supply1
Inv1
0.00
Supply1
Inv2
500
Supply1
Inv3
3000
Supply2
Inv1
500.00
Supply2
Inv2
2500.00
谢谢
使用window函数sum() over (partition by ... order by ...)
得到Amount
的累加和。使用 CASE
表达式根据累计金额有条件地检查 Deduction_Amount
以确定余额金额
select d.Supplier_Name,
d.Deduction_Amount,
s.Invoice_Number,
Invoice_Amount = s.Amount,
Balance = case when d.Deduction_Amount
>= sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
then 0
when d.Deduction_Amount
>= sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
- s.Amount
then sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
- d.Deduction_Amount
else s.Amount
end
from #Temp_Supply_Deduction d
inner join #Temp_Supply s on d.Supplier_Name = s.Supplier_Name
顺便说一句,你在问题中的预期输出是错误的
应该是
Supplier_Name
Deduction_Amount
Invoice_Number
Invoice_Amount
Balance
Supply1
2500.0000
Inv1
1000.0000
0.0000
Supply1
2500.0000
Inv2
2000.0000
500.0000
Supply1
2500.0000
Inv3
3000.0000
3000.0000
Supply2
500.0000
Inv1
1500.0000
1000.0000
Supply2
500.0000
Inv2
2500.0000
2500.0000
我有一个 SQL table 看起来像这样
CREATE TABLE #Temp_Supply
(
Supplier_Name Varchar(30),
Invoice_Number Varchar(20),
Amount Money
)
INSERT INTO #Temp_Supply (Supplier_Name, Invoice_Number, Amount)
SELECT 'Supply1', 'Inv1', 1000 UNION
SELECT 'Supply1', 'Inv2', 2000 UNION
SELECT 'Supply1', 'Inv3', 3000 UNION
SELECT 'Supply2', 'Inv1', 1500 UNION
SELECT 'Supply2', 'Inv2', 2500
CREATE TABLE #Temp_Supply_Deduction
(
Supplier_Name Varchar(30),
Deduction_Amount Money
)
INSERT INTO #Temp_Supply_Deduction(Supplier_Name, Deduction_Amount)
SELECT 'Supply1', 2500 UNION
SELECT 'Supply2', 500
SELECT * FROM #Temp_Supply
SELECT * FROM #Temp_Supply_Deduction
在选择供应时table从最小的发票编号开始扣除保留金额,直到金额用完
例外的输出应该是
Supplier_Name | Invoice_Number | Amount |
---|---|---|
Supply1 | Inv1 | 0.00 |
Supply1 | Inv2 | 500 |
Supply1 | Inv3 | 3000 |
Supply2 | Inv1 | 500.00 |
Supply2 | Inv2 | 2500.00 |
谢谢
使用window函数sum() over (partition by ... order by ...)
得到Amount
的累加和。使用 CASE
表达式根据累计金额有条件地检查 Deduction_Amount
以确定余额金额
select d.Supplier_Name,
d.Deduction_Amount,
s.Invoice_Number,
Invoice_Amount = s.Amount,
Balance = case when d.Deduction_Amount
>= sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
then 0
when d.Deduction_Amount
>= sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
- s.Amount
then sum(s.Amount) over (partition by d.Supplier_Name
order by s.Amount,
s.Invoice_Number)
- d.Deduction_Amount
else s.Amount
end
from #Temp_Supply_Deduction d
inner join #Temp_Supply s on d.Supplier_Name = s.Supplier_Name
顺便说一句,你在问题中的预期输出是错误的
应该是
Supplier_Name | Deduction_Amount | Invoice_Number | Invoice_Amount | Balance |
---|---|---|---|---|
Supply1 | 2500.0000 | Inv1 | 1000.0000 | 0.0000 |
Supply1 | 2500.0000 | Inv2 | 2000.0000 | 500.0000 |
Supply1 | 2500.0000 | Inv3 | 3000.0000 | 3000.0000 |
Supply2 | 500.0000 | Inv1 | 1500.0000 | 1000.0000 |
Supply2 | 500.0000 | Inv2 | 2500.0000 | 2500.0000 |