有没有一种简单的方法可以将值分布在多行中?
例如,我的表包含
Type Invoiced Paid Current Charge 100 0 100 Charge 100 0 100 Charge 100 0 100 Payment 0 250 0 Payment 0 25 0
The data is imported this way, but I need to populate the Current
and Paid
columns with whatever they should be for that transaction based on the payment transactions that were also imported.
Is there an easy way to write a query to determine the balance for the Current
column for each record?
For example, the 250 would apply 100 for the first two records and 50 to the next two, and the 25 would get applied to the last one, so the end result after updating the Current
balance in my table should be:
Type Invoiced Paid Current Charge 100 100 0 Charge 100 100 0 Charge 100 75 25 Payment 0 250 0 Payment 0 25 0
I'd ideally like to do this with a single query instead of using a cursor to process each item individually. I've been trying to do it by using the Row_Number() function and joining two subqueries, but I know I'm missing something here
Here was my first attempt, which resulted in getting the running total of the current balance
;with cte(invoiced, paid, current)
as (
select invoiced, paid, current
, row_number() over (order by datecreated)
from mytable
)
select t1.invoiced, t1.paid, sum(t2.invoiced - t2.paid) as [current]
from cte as t1
join cte as t2 on t1.number = t2.number and t2.rownum <= t1.rownum
group by t1.uid, t1.number, t1.rownum
order by t1.rownum
结果:
已开具发票的已付现款
100 0 100
100 0 200
100 0 300
0 250 50
0 25 25
我确信有办法做到这一点,但现在我的大脑似乎受到了打击,拒绝提出解决方案。
最佳答案
我想我找到了解决方案
首先,我不需要将付费交易链接到发票交易,所以我只需要所有付款的总和
select accountid, sum(paid)
from mytable
where type = 'Payment'
group by accountid
然后我需要将此值应用于每条记录,直到运行总数大于支付的总数。
为此,我修改了我的运行总查询,因此它只汇总费用而不是汇总费用和付款
;with cte(id, accountid, invoiced, paid, current)
as (
select id, accountid, invoiced, paid, current
, row_number() over (order by datecreated)
from mytable
where type = 'Charge'
)
select t1.id, t1.accountid, t1.invoiced, sum(t2.invoiced) as [runningTotalOfCharges]
from cte as t1
join cte as t2 on t1.number = t2.number and t2.rownum <= t1.rownum
group by t1.id, t1.accountid, t1.invoiced
并将其加入到付款查询中,所以现在我有一堆包含总付款金额、直到该记录的运行总费用以及当前记录的费用金额的行。
从那里,我只需要一个
CASE
语句来确定费用是全额支付、部分支付还是根本没有支付,并使用一点数学计算出Paid
和 Current
记录select charged.Id, charged.AccountId, charged.Invoiced
-- Use Case statements to determine if this payment is fully paid, partially paid,
-- or not paid at all, then determine Current and Paid based on that
, case when totalpaid - runningtotal >= 0 then invoiced
when invoiced > abs(totalpaid - runningtotal) then invoiced + totalpaid - runningtotal
else 0 end as [Paid]
, case when totalpaid - runningtotal >= 0 then 0
when invoiced > abs(totalpaid - runningtotal) then abs(totalpaid - runningtotal)
else invoiced end as [Current]
from
(
-- Running total query from above
select t1.id, t1.accountid, t1.invoiced, sum(t2.invoiced) as [runningtotal]
from cte as t1
join cte as t2 on t1.number = t2.number and t2.rownum <= t1.rownum
group by t1.id, t1.accountid, t1.invoiced
) as charged
inner join (
-- Total Paid query from above
select accountid, sum(paid) as totalpaid
from mytable
where type = 'Payment'
group by accountid
) as paid on charged.number = paid.number
而最终的结果正是我想要的。只需要通过
Id
将其加入到实际数据表中列,并更新 Paid
和 Current
值(value)观:)Id AccountId 已开票已付当前
1 1 100 100 0
2 1 100 100 0
3 1 100 75 25
关于sql - 如何在没有游标的情况下将值分布在多行中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12303795/