Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id 91A6647661D for ; Mon, 2 Dec 2002 14:19:23 -0500 (EST) Received: from temp.joelburton.com (65.eebed1.client.atlantech.net [209.190.238.101]) by postgresql.org (Postfix) with ESMTP id 9BD834769B0 for ; Mon, 2 Dec 2002 14:01:24 -0500 (EST) Received: by temp.joelburton.com (Postfix, from userid 501) id BCD0D2BA27; Mon, 2 Dec 2002 14:01:24 -0500 (EST) Date: Mon, 2 Dec 2002 14:01:24 -0500 From: Joel Burton To: Benjamin Smith Cc: pgsql-sql@postgresql.org Subject: Re: Accumulative Queries? Message-ID: <20021202190124.GA13254@temp.joelburton.com> References: <200211302240.gAUMe8c25335@host.effortlessis.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200211302240.gAUMe8c25335@host.effortlessis.com> User-Agent: Mutt/1.3.25i X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200212/14 X-Sequence-Number: 10602 On Sat, Nov 30, 2002 at 02:40:08PM -0800, Benjamin Smith wrote: > Let's say you have a table of Financial transactions: > > Create table checks ( > id serial, > number varchar, > to varchar, > amount real, > date integer > ); > > (date is an epoch timestamp) > > And you want to get a listing of checks > > "SELECT * FROM checks ORDER BY date ASC"; > > but you also want to have an accumulative field that adds up the amount field as the results are returned, so you might see results like: > > id number to amount date balance > 1 0 Deposit -100 12344 100 > 2 100 Jack 40 123455 60 > 3 101 Bob 20 123345 40 > 4 102 VOID 0 0 40 > 5 103 Harold 11 123488 29 > > Is this possible using only SQL? > > Also, assuming you have checks year round, how might you get results only in March that have totals consistent for the time frame while taking into account all the other checks in Jan and Feb? create table checks ( id serial primary key, num varchar unique, "to" varchar, amt real, date date ); insert into checks (num, "to", amt, date) values (0,'deposit',100,'2002-01-01'); insert into checks (num, "to", amt, date) values (0,'jack',40,'2002-02-01'); insert into checks (num, "to", amt, date) values (101,'jack',40,'2002-02-01'); insert into checks (num, "to", amt, date) values (102,'bob',20,'2002-02-01'); insert into checks (num, "to", amt, date) values (103,'VOID',0,'2002-02-01'); insert into checks (num, "to", amt, date) values (104,'jenny',10,'2002-03-01'); insert into checks (num, "to", amt, date) values (104,'raul',10,'2002-03-02'); insert into checks (num, "to", amt, date) values (105,'raul',10,'2002-03-02'); select *, ( select sum(amt) from checks c2 where c2.id<=c1.id as c2) from checks c1; will give you the full accounting. To get just March, put a where-date-between clause in both the outer and inner queries. This will run slowly, though, for many transactions. Either consider: * "closing" an account every month/quarter/year/whenever will the aggregate-so-far, and having your query use that, and do the math from that point onwards * store the running balance in the table, and use triggers to keep it up to date for inserts/updates/deletes -- Joel BURTON | joel@joelburton.com | joelburton.com | aim: wjoelburton Independent Knowledge Management Consultant