SQL Server Forums
Profile | Register | Active Topics | Members | Search | Forum FAQ
 
Register Now and get your question answered!
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Balance calculations
 New Topic  Reply to Topic
 Printer Friendly
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 11/21/2007 :  20:57:18  Show Profile  Reply with Quote
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  Show Profile  Visit tkizer's Homepage  Reply with Quote
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/
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 11/23/2007 :  06:55:25  Show Profile  Reply with Quote
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
Go to Top of Page

tkizer
Almighty SQL Goddess

USA
35017 Posts

Posted - 11/23/2007 :  17:30:33  Show Profile  Visit tkizer's Homepage  Reply with Quote
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/
Go to Top of Page

georgev
Posting Yak Master

United Kingdom
122 Posts

Posted - 11/26/2007 :  05:52:59  Show Profile  Reply with Quote
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!
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 11/28/2007 :  06:28:27  Show Profile  Reply with Quote
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
Go to Top of Page

Jeff Moden
Aged Yak Warrior

USA
644 Posts

Posted - 12/01/2007 :  21:42:50  Show Profile  Reply with Quote
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
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/02/2007 :  02:28:49  Show Profile  Reply with Quote
hello Georgev,

still waiting on your solution..

thanks

carlossiwaily
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/22/2007 :  13:13:17  Show Profile  Reply with Quote
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
Go to Top of Page

Jeff Moden
Aged Yak Warrior

USA
644 Posts

Posted - 12/23/2007 :  03:10:13  Show Profile  Reply with Quote
carlossiwaily,

How many rows and how many accounts do you have in your table that you need balances for?

--Jeff Moden
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/23/2007 :  13:36:44  Show Profile  Reply with Quote
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
Go to Top of Page

TG
Flowing Fount of Yak Knowledge

USA
5501 Posts

Posted - 12/23/2007 :  14:03:58  Show Profile  Reply with Quote
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
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/23/2007 :  15:45:44  Show Profile  Reply with Quote
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
Go to Top of Page

TG
Flowing Fount of Yak Knowledge

USA
5501 Posts

Posted - 12/23/2007 :  16:37:38  Show Profile  Reply with Quote
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
Go to Top of Page

TG
Flowing Fount of Yak Knowledge

USA
5501 Posts

Posted - 12/23/2007 :  17:09:08  Show Profile  Reply with Quote
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
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/23/2007 :  17:19:49  Show Profile  Reply with Quote
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
Go to Top of Page

carlossiwaily
Starting Member

United Kingdom
24 Posts

Posted - 12/23/2007 :  17:32:23  Show Profile  Reply with Quote
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
Go to Top of Page

TG
Flowing Fount of Yak Knowledge

USA
5501 Posts

Posted - 12/23/2007 :  18:03:18  Show Profile  Reply with Quote
>>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
Go to Top of Page

Jeff Moden
Aged Yak Warrior

USA
644 Posts

Posted - 12/23/2007 :  18:55:46  Show Profile  Reply with Quote
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
Go to Top of Page

TG
Flowing Fount of Yak Knowledge

USA
5501 Posts

Posted - 12/23/2007 :  19:11:56  Show Profile  Reply with Quote
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
Go to Top of Page

Jeff Moden
Aged Yak Warrior

USA
644 Posts

Posted - 12/23/2007 :  21:23:18  Show Profile  Reply with Quote
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
Go to Top of Page
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
SQL Server Forums © 2000-2009 SQLTeam Publishing, LLC Go To Top Of Page
This page was generated in 1.4 seconds. Powered By: Snitz Forums 2000