X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id ABB1953DCB for ; Sat, 23 Apr 2005 09:06:13 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 13483-06 for ; Sat, 23 Apr 2005 12:06:03 +0000 (GMT) Received: from mx5.net.nih.gov (mx5.net.nih.gov [165.112.130.36]) by svr1.postgresql.org (Postfix) with ESMTP id 41D5D53DA4 for ; Sat, 23 Apr 2005 09:06:00 -0300 (ADT) Received: from mx5.net.nih.gov (localhost [127.0.0.1]) by mx5.net.nih.gov (8.12.10/8.11.6) with ESMTP id j3NC63as005670 for ; Sat, 23 Apr 2005 08:06:03 -0400 Received: from WATSON (vpn-165-112-10-48.net.nih.gov [165.112.10.48]) by mx5.net.nih.gov (8.12.10/8.11.6) with SMTP id j3NC5wKe005626; Sat, 23 Apr 2005 08:06:02 -0400 Message-ID: <000c01c547fc$cf93fc80$5179f345@WATSON> From: "Sean Davis" To: "Tony Wasson" , References: <6d8daee30504211821515e7f11@mail.gmail.com> Subject: Re: Looking for a way to sum integer arrays.... Date: Sat, 23 Apr 2005 08:05:58 -0400 MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.2180 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.076 tagged_above=0 required=5 tests=AWL X-Spam-Level: X-Archive-Number: 200504/355 X-Sequence-Number: 21248 You would definitely want to look into using pl/R for this. Also, other procedure languages (perl, for example) work well with arrays so may be easier to use for this situation. As for the aggregate, I don't know how to make that more dynamic in terms of return value. Sean ----- Original Message ----- From: "Tony Wasson" To: Sent: Thursday, April 21, 2005 9:21 PM Subject: [SQL] Looking for a way to sum integer arrays.... I'd like to be able to sum up an integer array. Like so: {3,2,1} + {0,2,2} ------- {3,4,3} The following solution I've been hacking on works, although I think it is far from "ideal". Is there a built in way to sum up arrays? If not, is there a better way than my crude method? I have tested this on 7.4 and 8.0. I'd also be appreciate if any insight on why my aggregate fails to work when I have an empty initcondition. P.S. I have never written an aggregate and I was lost trying to follow the complex_sum example in the docs. --------------------------------------------- CREATE OR REPLACE FUNCTION sum_intarray(INTEGER[],INTEGER[]) RETURNS INTEGER[] LANGUAGE 'plpgsql' AS ' /* || Author: Tony Wasson || || Overview: Experiment with arrays and aggregates || 3,2,1 || + 0,2,2 || ------- || 3,4,3 || || Revisions: (when, who, what) || 2005/04/21 -- TW - Create function */ DECLARE inta1 ALIAS FOR $1; inta2 ALIAS FOR $2; out_arr INTEGER[]; out_arr_text TEXT := ''''; i INTEGER; nextnum INTEGER; BEGIN FOR i IN array_lower(inta1, 1)..array_upper(inta1, 1) LOOP RAISE NOTICE ''looking at element %'',i; nextnum := COALESCE(inta1[i],0) + COALESCE(inta2[i],0); RAISE NOTICE ''nextnum %'',nextnum; out_arr_text := out_arr_text || nextnum::TEXT || '',''; RAISE NOTICE ''text %'',out_arr_text; END LOOP; RAISE NOTICE ''text %'',out_arr_text; --drop the last comma IF SUBSTRING(out_arr_text,length(out_arr_text),1) = '','' THEN out_arr_text := substring(out_arr_text,1,length(out_arr_text)-1); END IF; out_arr_text := ''{'' || out_arr_text || ''}''; RAISE NOTICE ''text %'',out_arr_text; out_arr := out_arr_text; RAISE NOTICE ''out_arr %'',out_arr; RETURN out_arr; END '; SELECT sum_intarray('{1,2}','{2,3}'); SELECT sum_intarray('{3,2,1}','{0,2,2}'); --- Now I make a table to demonstrate an aggregate on CREATE TABLE arraytest ( id character varying(10) NOT NULL, somearr integer[] ); INSERT INTO arraytest (id, somearr) VALUES ('a', '{1,2,3}'); INSERT INTO arraytest (id, somearr) VALUES ('b', '{0,1,2}'); CREATE AGGREGATE sum_integer_array ( sfunc = sum_intarray, basetype = INTEGER[], stype = INTEGER[], initcond = '{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}' ); ---------------------- # SELECT sum_integer_array(somearr) FROM arraytest; sum_integer_array --------------------------------------------------------------------------------- {1,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}Thanks in advance to anyone who reads this far.Tony Wassonajwasson@gmail.com---------------------------(end of broadcast)---------------------------TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to majordomo@postgresql.org so that your message can get through to the mailing list cleanly