我使用以下代码来计算帐单,但当我的记录转到100k我的应用程序返回超时错误时,让我知道如何重写它以提高性能???
注意: 我有借记和贷记记录,我的结果是BALANCE和STATUS。
declare @lbalance decimal=0 , @credit decimal=0 , @debit decimal=0 , @new_balance decimal=0,@balance decimal=0
DECLARE q1_cursor CURSOR DYNAMIC for select debit,credit,balance,[status] from #t1
open q1_cursor
fetch next from q1_cursor into @debit,@credit,@lbalance,@st
while @@fetch_status=0
begin
set @new_balance=@new_balance+isnull(@credit,0)-isnull(@debit,0)
if(@new_balance>1)
begin
set @st='creditor'
set @balance=@new_balance
end
else
begin
set @st='debtor'
set @balance=@new_balance*-1
end
update #t1 set balance=@balance,[status]=@st where current of q1_cursor
fetch next from q1_cursor into @debit,@credit,@lbalance,@st
end
close q1_cursor
deallocate q1_cursor
select * from #t1
修改
我重写了你的代码,但是,我得到了错误! “递归查询”HierarchicalCTE“列”Balance“中的锚和递归部分之间的类型不匹配。”我该怎么办?
with HierarchicalCTE (ID,Date, Debit, Credit, Balance, [Status]) As
(
select ID,Date, Debit, Credit, Balance, [Status]
from #t1
where ID = 1
union all
select tbl.ID,tbl.Date, tbl.Debit, tbl.Credit
, Balance=(case when ((tbl.Debit > 0 and cte.[Status] = 'debtor') or (tbl.Credit > 0 and cte.[Status] = 'creditor')) then abs(cte.Balance + tbl.Debit)
when tbl.Debit > 0 and cte.[Status] = 'creditor' then abs(cte.Balance - tbl.Debit)
else abs(cte.Balance - tbl.Credit)
end)
, cast(case when ((tbl.Debit > 0 and cte.[Status] = 'debtor') or (tbl.Debit > 0 and tbl.Debit > cte.Balance)) then 'debtor'
else 'creditor'
end as char(20)) as [Status]
from #t1 tbl
inner join HierarchicalCTE cte
on tbl.ID = cte.ID+1
)
select * from HierarchicalCTE
答案 0 :(得分:1)
假设您的起始行有debit = 200, credit = 0, balance = 200, status = debtor
,并且您希望将值输入余额和其余行的状态。
基于假设使用公用表表达式(CTE)的示例,表中有一个ID列。
declare @tbl table (id int, debit money, credit money, balance money, [status] varchar(20))
insert into @tbl (id, debit, credit, balance, [status])
values (1, 200, 0, 200, 'debtor')
, (2, 0, 300, 0, '')
, (3, 50, 0, 0, '')
, (4, 100, 0, 0, '')
; with cte (id, debit, credit, balance, [status])
as
(
select id, debit, credit, balance, [status]
from @tbl
where id = 1
union all
select tbl.id, tbl.debit, tbl.credit
, case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.credit > 0 and cte.[status] = 'creditor')) then abs(cte.balance + tbl.debit)
when tbl.debit > 0 and cte.[status] = 'creditor' then abs(cte.balance - tbl.debit)
else abs(cte.balance - tbl.credit)
end as balance
, cast(case when ((tbl.debit > 0 and cte.[status] = 'debtor') or (tbl.debit > 0 and tbl.debit > cte.balance)) then 'debtor'
else 'creditor'
end as varchar(20)) as [status]
from @tbl tbl
inner join cte cte
on tbl.id = cte.id + 1
)
select * from cte
初始数据..
id debit credit balance status
1 200.00 0.00 200.00 debtor
2 0.00 300.00 0.00
3 50.00 0.00 0.00
4 100.00 0.00 0.00
结果..
id debit credit balance status
1 200.00 0.00 200.00 debtor
2 0.00 300.00 100.00 creditor
3 50.00 0.00 50.00 creditor
4 100.00 0.00 50.00 debtor