X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [64.117.224.130]) by svr1.postgresql.org (Postfix) with ESMTP id 3B244D1B4FC for ; Sat, 11 Oct 2003 18:44:20 +0000 (GMT) Received: from svr1.postgresql.org ([64.117.224.193]) by localhost (neptune.hub.org [64.117.224.130]) (amavisd-new, port 10024) with ESMTP id 05421-10 for ; Sat, 11 Oct 2003 15:43:39 -0300 (ADT) Received: from anchor-post-31.mail.demon.net (anchor-post-31.mail.demon.net [194.217.242.89]) by svr1.postgresql.org (Postfix) with ESMTP id EAC68D1B526 for ; Sat, 11 Oct 2003 15:43:29 -0300 (ADT) Received: from mwynhau.demon.co.uk ([193.237.186.96] helo=mainbox.archonet.com) by anchor-post-31.mail.demon.net with esmtp (Exim 3.35 #1) id 1A8OiL-000C9k-0V; Sat, 11 Oct 2003 19:43:41 +0100 Received: from localhost (localhost.localdomain [127.0.0.1]) by mainbox.archonet.com (Postfix) with ESMTP id 729D316616; Sat, 11 Oct 2003 19:43:40 +0100 (BST) Received: from client17.archonet.com (client17.archonet.com [192.168.1.17]) by mainbox.archonet.com (Postfix) with ESMTP id C1B3815982; Sat, 11 Oct 2003 19:43:39 +0100 (BST) From: Richard Huxton To: Christopher Kings-Lynne , pgsql-sql@postgresql.org Subject: Re: Running tally Date: Sat, 11 Oct 2003 19:43:38 +0100 User-Agent: KMail/1.5 References: <3F7E9956.30804@familyhealth.com.au> In-Reply-To: <3F7E9956.30804@familyhealth.com.au> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200310111943.38792.dev@archonet.com> X-Virus-Scanned: by AMaViS snapshot-20020531 X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200310/122 X-Sequence-Number: 15522 On Saturday 04 October 2003 10:56, Christopher Kings-Lynne wrote: > Hi guys, > > If I have a table that is just a single column full of numbers, how can > I select all the rows from the table with a second column that is the > running tally so far down the result set? > > eg: > > Num Tally so far > 0.3 0.3 > 1.2 1.5 > 2.0 3.5 > ... > > Does this require PL/PgSQL coding? If so, how do you actually construct > an arbitrary row for returning? The docs are somewhat unclear on this. Did you post this days ago, or is your/my clock wrong - it reads 2003-10-04 in my mailer? Anyway, you could do it with a sub-query, but performance will be less than great with a large result-set. SELECT * FROM runtot ; idx | num -----+----- 1 | 10 2 | 20 3 | 30 CREATE FUNCTION runtot_sum(int4) RETURNS int4 AS 'SELECT sum(num)::int4 FROM runtot WHERE idx <= $1' LANGUAGE 'SQL'; SELECT idx, num, runtot_sum(idx) FROM runtot ORDER BY idx; idx | num | runtot_sum -----+-----+------------ 1 | 10 | 10 2 | 20 | 30 3 | 30 | 60 Procedural is the way to go if you have a large result set. Stephan Szabo has written some good notes on set-returning functions: http://techdocs.postgresql.org/guides/SetReturningFunctions Basically, define a type: CREATE TYPE run_tot_type AS ( a whatever, b whatever, run_tot whatever ); Then: CREATE FUNCTION my_run_tot() RETURNS SETOF run_tot_type AS... Accumulate your values in a record-type variable and use RETURN NEXT to issue each row. HTH -- Richard Huxton Archonet Ltd