Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-11-21 : 20:57:18
|
HelloI have a table as followT1(Tranid(pk),accountnumber,payin,payout, balance)My problem is after insert how to update the balance Filed accordingly If payin > 0 thenUpdate T1 Set balance = ( get balance of previous record where = accountnumber) + @payinWhere tranid = @@identityElse if payout >0Update t1 Set balance = ( get balance of previous record then where = accountnumber ) - @payinWhere tranid = @@identityWhat I really want to achieve is to have same as bank statementDate Payin payout Balance20/11/2007 1000 0 100021/11/2007 0 500 500Any help pleaseMany Thankscarlossiwaily |
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2007-11-21 : 23:04:33
|
Shouldn't you just take care of this on the inserts?IF @payin > 0INSERT INTO t1 (accountnumber, payin, payout, balance)SELECT @acctno, @payin, @payout, balance + @payinFROM t1WHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)IF @payout > 0INSERT INTO t1 (accountnumber, payin, payout, balance)SELECT @acctno, @payin, @payout, balance - @payinFROM t1WHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/ |
 |
|
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-11-23 : 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 > 0IF (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)> 0INSERT INTO t1 (accountnumber, payin, payout, balance)SELECT @acctno, @payin, @payout, balance + @payinWHERE tranid = (SELECT MAX(tranid) FROM t1 WHERE accountnumber = @acctno)FROM t1ElseINSERT INTO t1 (accountnumber, payin, payout, balance)Values(@acctno, @payin, @payout, @payin)Is there a better whys of solve the issue Many Thankscarlossiwaily |
 |
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2007-11-23 : 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 KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/ |
 |
|
georgev
Posting Yak Master
122 Posts |
Posted - 2007-11-26 : 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
24 Posts |
Posted - 2007-11-28 : 06:28:27
|
hi,Many Thanks Tara for your helpGeorgev, 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
652 Posts |
Posted - 2007-12-01 : 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
24 Posts |
Posted - 2007-12-02 : 02:28:49
|
hello Georgev,still waiting on your solution..thankscarlossiwaily |
 |
|
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-12-22 : 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 thankscarlossiwaily |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-12-23 : 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
24 Posts |
Posted - 2007-12-23 : 13:36:44
|
Hello JeffTransactiontable(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 .Thankscarlossiwaily |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-23 : 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 OptimizerTG |
 |
|
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-12-23 : 15:45:44
|
HelloI have table tran(Date,debit,credit,accountid)data 12/12/2008,0,100,113/12/2008,0,200,114/12/2008,50,0,1Now I want to achive the followoing using sql1. Date Debit Credit, Balance12/12/2008 0 100 10013/12/2008 0 200 30014/12/2008 50 0 250How do i write sql qury to get the above result for give accountid = 1The result may return over 100,000 records so performance is very important Many Thankscarlossiwaily |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-23 : 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 OptimizerTG |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-23 : 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, accountidfrom ( 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 ) aorder by dateselect date ,debit ,credit ,balance = (select sum(credit - debit) from #tran where accountid = a.accountid and tranid <= a.tranid)from #tran awhere a.accountid = 1order by tranid--EDIT:print 'alternate technique'select a.date ,a.debit ,a.credit ,sum(b.credit - b.debit) balancefrom #tran ajoin #tran b on a.accountid = b.accountid and a.tranid >= b.tranidgroup by a.accountid ,a.tranid ,a.date ,a.debit ,a.creditorder by a.accountid, a.tranid--/EDITdrop table #tranoutput:date debit credit balance ------------------------------------------------------------- --------------------- --------------------- 2008-12-12 00:00:00.000 .0000 100.0000 100.00002008-12-13 00:00:00.000 .0000 200.0000 300.00002008-12-14 00:00:00.000 50.0000 .0000 250.0000 Be One with the OptimizerTG |
 |
|
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-12-23 : 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 flythanks for your helpcarlossiwaily |
 |
|
carlossiwaily
Starting Member
24 Posts |
Posted - 2007-12-23 : 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 thankscarlossiwaily |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-23 : 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 dataset dateformat 'dmy'insert #tran (date, debit, credit, accountid)select date, debit, credit, accountidfrom ( 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 ) aorder by dateset dateformat 'ymd'--input parametersdeclare @fromDate datetime ,@toDate datetime ,@acctid intselect @fromDate = '2008-12-14' ,@toDate = '2008-12-15' ,@acctid = 1--local variablesdeclare @begBal money, @begTranID int--get the beginning tranID and Balance for earliest date up to (but not including) @fromDateselect @begBal = sum(credit - debit) ,@begTranID = max(tranid)from #tranwhere accountid = @acctidand date < @fromDate--Get details from @fromDate through @ToDateselect date ,debit ,credit ,balance = @begBal + (select sum(credit - debit) from #tran where tranid > @begTranid and accountid = a.accountid and tranid <= a.tranid)from #tran awhere a.accountid = @acctIDand tranid > @begTranidand date <= @toDate--EDIT:print 'alternate technique - maybe faster?'select a.date ,a.debit ,a.credit ,@begBal + sum(b.credit - b.debit) balancefrom #tran ajoin #tran b on a.accountid = b.accountid and a.tranid >= b.tranid and b.tranid > @begTranidwhere a.tranid > @begTranidand a.date <= @toDategroup by a.accountid ,a.tranid ,a.date ,a.debit ,a.creditorder by a.accountid, a.tranid--/EDITdrop table #tranoutput:date debit credit balance -------------------------------------------------------- --------------------- --------------------- 2008-12-14 00:00:00.000 50.0000 .0000 250.00002008-12-15 00:00:00.000 .0000 200.0000 450.0000 Be One with the OptimizerTG |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-12-23 : 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
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-23 : 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 OptimizerTG |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-12-23 : 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. |
 |
|
Next Page
|
|
|
|
|