| Author |
Topic  |
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 11/21/2007 : 20:57:18
|
Hello
I have a table as follow
T1(Tranid(pk),accountnumber,payin,payout, balance)
My problem is after insert how to update the balance Filed accordingly
If payin > 0 then
Update T1 Set balance = ( get balance of previous record where = accountnumber) + @payin Where tranid = @@identity
Else if payout >0
Update t1 Set balance = ( get balance of previous record then where = accountnumber ) - @payin Where tranid = @@identity
What I really want to achieve is to have same as bank statement
Date Payin payout Balance 20/11/2007 1000 0 1000 21/11/2007 0 500 500
Any help please
Many Thanks
carlossiwaily |
|
|
tkizer
Almighty SQL Goddess
USA
35017 Posts |
Posted - 11/21/2007 : 23:04:33
|
Shouldn't you just take care of this on the inserts?
IF @payin > 0 INSERT INTO t1 (accountnumber, payin, payout, balance) SELECT @acctno, @payin, @payout, balance + @payin FROM t1 WHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)
IF @payout > 0 INSERT INTO t1 (accountnumber, payin, payout, balance) SELECT @acctno, @payin, @payout, balance - @payin FROM t1 WHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)
Tara Kizer Microsoft MVP for Windows Server System - SQL Server http://weblogs.sqlteam.com/tarad/ |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 11/23/2007 : 06:55:25
|
Hello Tara, Thanks for your help.. your solution solves my problem when the Tranid > 0 it all OK . But when the tranid = Null 0r 0 the balance + @payin = 0 at all time. So i have used the following to solve the isuess.
IF @payin > 0 IF (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)> 0
INSERT INTO t1 (accountnumber, payin, payout, balance) SELECT @acctno, @payin, @payout, balance + @payin WHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno) FROM t1 Else
INSERT INTO t1 (accountnumber, payin, payout, balance) Values(@acctno, @payin, @payout, @payin)
Is there a better whys of solve the issue
Many Thanks
carlossiwaily |
 |
|
|
tkizer
Almighty SQL Goddess
USA
35017 Posts |
Posted - 11/23/2007 : 17:30:33
|
You should save the MAX tranid value into a variable since you are using the same subquery twice. You'll get better performance this way since you won't have to grab that value twice.
Tara Kizer Microsoft MVP for Windows Server System - SQL Server http://weblogs.sqlteam.com/tarad/ |
 |
|
|
georgev
Posting Yak Master
United Kingdom
122 Posts |
Posted - 11/26/2007 : 05:52:59
|
Correct me if I'm wrong, but shouldn't the balance be worked out on the fly rather than stored?
It would also be fairly simple to produce a query with a running sum total to make the results look like a bank statement.
George <3Engaged! |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 11/28/2007 : 06:28:27
|
hi, Many Thanks Tara for your help
Georgev, Yes you are right . that what i wanted but i really could not get it to work .. do you have any example? Many Thanks.
carlossiwaily |
 |
|
|
Jeff Moden
Aged Yak Warrior
USA
644 Posts |
Posted - 12/01/2007 : 21:42:50
|
quote: It would also be fairly simple to produce a query with a running sum total to make the results look like a bank statement.
So, let's see it!
--Jeff Moden |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/02/2007 : 02:28:49
|
hello Georgev,
still waiting on your solution..
thanks
carlossiwaily |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/22/2007 : 13:13:17
|
hello,
any advice on how to create balance column on the fly or any samples how to create a bank statment.. I do not mind to pay for the code ..
many thanks
carlossiwaily |
 |
|
|
Jeff Moden
Aged Yak Warrior
USA
644 Posts |
Posted - 12/23/2007 : 03:10:13
|
carlossiwaily,
How many rows and how many accounts do you have in your table that you need balances for?
--Jeff Moden |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/23/2007 : 13:36:44
|
Hello Jeff
Transactiontable(date, debit,credit,accountid) This table will have transactions for over 1000 diffrent accounts, so this means the table will grow really big. i would like to provide my client with monthly statment for each account.
Can you please help .
Thanks
carlossiwaily |
 |
|
|
TG
Flowing Fount of Yak Knowledge
USA
5501 Posts |
Posted - 12/23/2007 : 14:03:58
|
Just to throw my 2 cents in:
I agree with georgev that you should not maintain a [balance] column in a detailed transaction table. Especially if the transaction table is written to often and under high concurrency. The customer statement (as a report) should handle the balance calculation. You only need to know the balance for that report, right? Not every time a transaction is written?
If that is the case your inserts become very easy. Depending on your reporting presentation layer you may be able to handle the balance calc in there. If you need help with a query to talley up the balance based on your transactions let us know.
Be One with the Optimizer TG |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/23/2007 : 15:45:44
|
Hello
I have table
tran(Date,debit,credit,accountid)
data
12/12/2008,0,100,1
13/12/2008,0,200,1
14/12/2008,50,0,1
Now I want to achive the followoing using sql
1. Date Debit Credit, Balance
12/12/2008 0 100 100
13/12/2008 0 200 300
14/12/2008 50 0 250
How do i write sql qury to get the above result for give accountid = 1
The result may return over 100,000 records so performance is very important
Many Thanks
carlossiwaily |
 |
|
|
TG
Flowing Fount of Yak Knowledge
USA
5501 Posts |
Posted - 12/23/2007 : 16:37:38
|
a couple questions:
- A bank statement usually is for a specific period, like 1 calendar month. Do you really need to return a complete history with every report? 100K row report is useless in my opinion.
- My bank statement just lists all the activity (without a rolling balance) then shows the beginning and ending balance. Is this an option for you or you need the rolling balance at each transaction?
- do you really only need to get the report for one account at a time?
EDIT: I may reverse my (earlier stated) opinion about not storing the balance. If you really need to report a rolling balance at each transaction over 100K rows (for each account) then it may make more sense to store the value. Tara (tkizer) had a pretty good solution for doing that in the insert.
Be One with the Optimizer TG |
Edited by - TG on 12/23/2007 16:53:28 |
 |
|
|
TG
Flowing Fount of Yak Knowledge
USA
5501 Posts |
Posted - 12/23/2007 : 17:09:08
|
This would probably be pretty slow over 100,000 rows but here is one option are two options for Sql2000 for getting a rolling balance:
create table #tran(tranid int identity(1,1), Date datetime,debit money,credit money,accountid int)
set dateformat 'dmy'
insert #tran (date, debit, credit, accountid)
select date, debit, credit, accountid
from (
select '12/12/2008' date ,0 debit ,100 credit, 1 accountid union all
select '13/12/2008',0,200,1 union all
select '14/12/2008',50,0,1
) a
order by date
select date
,debit
,credit
,balance =
(select sum(credit - debit)
from #tran
where accountid = a.accountid and tranid <= a.tranid)
from #tran a
where a.accountid = 1
order by tranid
--EDIT:
print 'alternate technique'
select a.date
,a.debit
,a.credit
,sum(b.credit - b.debit) balance
from #tran a
join #tran b
on a.accountid = b.accountid
and a.tranid >= b.tranid
group by a.accountid
,a.tranid
,a.date
,a.debit
,a.credit
order by a.accountid, a.tranid
--/EDIT
drop table #tran
output:
date debit credit balance
------------------------------------------------------------- --------------------- ---------------------
2008-12-12 00:00:00.000 .0000 100.0000 100.0000
2008-12-13 00:00:00.000 .0000 200.0000 300.0000
2008-12-14 00:00:00.000 50.0000 .0000 250.0000
Be One with the Optimizer TG |
Edited by - TG on 12/24/2007 10:08:12 |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/23/2007 : 17:19:49
|
Many Thanks TG,
1. The Reports (statemts) can be per calendar month too. 2. It is better to show the balance at each transaction (as in real bank statment). 3. Yes, like to pass veriables fromdate, todate, accountid to the sql qury.
Well, to store the balance at each transaction has giveen me a lots of problems e.g when the user try to delete/edit a transaction then the value stored the balance column will all be incorect.
I would like to calculate the balance on fly
thanks for your help
carlossiwaily |
 |
|
|
carlossiwaily
Starting Member
United Kingdom
24 Posts |
Posted - 12/23/2007 : 17:32:23
|
hello,
thank you very much for the code.. it works ok .. I would like the qury returns result per calender month. How would you calculate the correct balance .
Many thanks
carlossiwaily |
 |
|
|
TG
Flowing Fount of Yak Knowledge
USA
5501 Posts |
Posted - 12/23/2007 : 18:03:18
|
>>like to pass veriables fromdate, todate, accountid to the sql qury. >>I would like the qury returns result per calender month. How would you calculate the correct balance
Here is one way:
create table #tran(tranid int identity(1,1), Date datetime,debit money,credit money,accountid int)
--set up sample data
set dateformat 'dmy'
insert #tran (date, debit, credit, accountid)
select date, debit, credit, accountid
from (
select '12/12/2008' date ,0 debit ,100 credit, 1 accountid union all
select '13/12/2008',0,200,1 union all
select '14/12/2008',50,0,1 union all
select '15/12/2008',0,200,1 union all
select '16/12/2008',50,0,1 union all
select '17/12/2008',0,200,1
) a
order by date
set dateformat 'ymd'
--input parameters
declare @fromDate datetime
,@toDate datetime
,@acctid int
select @fromDate = '2008-12-14'
,@toDate = '2008-12-15'
,@acctid = 1
--local variables
declare @begBal money, @begTranID int
--get the beginning tranID and Balance for earliest date up to (but not including) @fromDate
select @begBal = sum(credit - debit)
,@begTranID = max(tranid)
from #tran
where accountid = @acctid
and date < @fromDate
--Get details from @fromDate through @ToDate
select date
,debit
,credit
,balance = @begBal +
(select sum(credit - debit)
from #tran
where tranid > @begTranid
and accountid = a.accountid
and tranid <= a.tranid)
from #tran a
where a.accountid = @acctID
and tranid > @begTranid
and date <= @toDate
--EDIT:
print 'alternate technique - maybe faster?'
select a.date
,a.debit
,a.credit
,@begBal + sum(b.credit - b.debit) balance
from #tran a
join #tran b
on a.accountid = b.accountid
and a.tranid >= b.tranid
and b.tranid > @begTranid
where a.tranid > @begTranid
and a.date <= @toDate
group by a.accountid
,a.tranid
,a.date
,a.debit
,a.credit
order by a.accountid, a.tranid
--/EDIT
drop table #tran
output:
date debit credit balance
-------------------------------------------------------- --------------------- ---------------------
2008-12-14 00:00:00.000 50.0000 .0000 250.0000
2008-12-15 00:00:00.000 .0000 200.0000 450.0000
Be One with the Optimizer TG |
Edited by - TG on 12/24/2007 09:17:01 |
 |
|
|
Jeff Moden
Aged Yak Warrior
USA
644 Posts |
Posted - 12/23/2007 : 18:55:46
|
The problem with all of that is that the <= forms a triangular join. Right now, with the small number of records in the table (100,000), and 1,000 accounts, you only have an average of about 100 rows per account. Internally, that means that each of the 1000 accounts will generate (100*100+100)/2 rows or 5,050 rows for each account. Try that with a 1000 rows per account and see what you get.
Lemme know when you need something that will calculate a couple of million rows in a few seconds.
--Jeff Moden |
 |
|
|
TG
Flowing Fount of Yak Knowledge
USA
5501 Posts |
Posted - 12/23/2007 : 19:11:56
|
quote: Originally posted by Jeff Moden
Lemme know when you need something that will calculate a couple of million rows in a few seconds.
Absolutely - by all means - don't just tease us I'm sure the OP would greatly appreciate it and I always like to see better ways to do stuff.
Be One with the Optimizer TG |
 |
|
|
Jeff Moden
Aged Yak Warrior
USA
644 Posts |
Posted - 12/23/2007 : 21:23:18
|
My applogies... I didn't mean to tease... didn't want to take the time to do the full demo if the OP doesn't need it. I'll work up the demo code and come back.
--Jeff Moden
(Edit) See next page for a 4,000,000 row example complete with a test data generator. |
Edited by - Jeff Moden on 12/24/2007 00:44:12 |
 |
|
Topic  |
|
|
|